0

I'm having a great deal of difficulty iterating over a simple nested json. For some reason I cannot seem to get my desired output. I am looking to iterate over :

{
    "onShift": {
       "fastTrack1": {
         "name": "Bob, bob",
         "shift": "7a-7p",
         "service": "Fasttrack",
         "spectra": "722413",
         "office": "",
         "cell": ""
       },
       "fastTrack2": {
         "name": "Bill, Bill",
         "shift": "7a-7p",
         "service": "Fasttrack2",
         "spectra": "54827",
         "office": "",
         "cell": "123-456-9090"
       },
      
       "incoming": {
         "incoming_fastTrack1": {
           "name": "Billy, Bob",
           "shift": "7p-7a",
           "service": "Fasttrack",
           "spectra": "54821",
           "office": "",
           "cell": "123-456-8909"
       },
       "incoming_fastTrack2": {
         "name": "Funny, Bob",
         "shift": "7p-7a",
         "service": "Fasttrack2",
         "spectra": "3478",
         "office": "",
         "cell": ""
       },
      
       "shiftEnd": {
         "ended_E_MD": {
           "name": "Kissy Bob",
           "shift": "7a-3p",
           "service": "Area E",
           "spectra": "3281",
           "office": "",
           "cell": "123-456-12345"
         },
         "ended_D_MD": {
           "name": "funky bob",
           "shift": "7a-3p",
           "service": "Area D",
           "spectra": "0003",
           "office": "",
           "cell": ""
         },
         "ended_DE_MD": {
           "name": "Jimmy, Bob",
           "shift": "10a-6p",
           "service": "Area D-E",
           "spectra": "0002",
           "office": "",
           "cell": ""
         },
         "ended_Tr_MD": {
           "name": "Jim, Bob",
           "shift": "8a-4p",
           "service": "Triage",
           "spectra": "0001",
           "office": "",
           "cell": ""
         }
       }
}

How I am trying to iterate is like this (one of the many way's I've tried):

$.getJSON("../data/json/erCall.json", function(data){
        for (var i in data['onShift']){
           
        var name = data['onShift'][i].name;
        var spec = data['onShift'][i].service;
        var shift = data['onShift'][i].shift;
        var cell = data['onShift'][i].cell;
        var off  = data['onShift'][i].office;
        
$("#dataTargetOnCall").append('<tr><td>'+name+'</td><td>'+service+'</td>...etc');
        }
     
    });

I've also tried:

 $.getJSON("../data/json/erCall.json", function(data){
            for (var i in data){
              for (var j in data[i]){
           
        var name = data[i]['onShift'].name;
        var spec = data[i]['onShift'].service;
        var shift = data[i]['onShift'].shift;
        var cell = data[i]['onShift'].cell;
        var off  = data[i]['onShift'].office;

... and so on

My intention is to iterate all of the listings under "onShift" and output all of the items (about 20) into a table. It basically outputs which doctors are on shift. I know how to format the append() function, however that's only after I am able to capture the data from the JSON of course.

What can I try next?

halfer
  • 19,824
  • 17
  • 99
  • 186
Jrapa86
  • 129
  • 1
  • 10
  • make sure your json is in a valid format – Marik Ishtar Jun 25 '20 at 02:42
  • I'm pretty sure that it is. When it is one less level (and not nested) and in the same format, it seems to work okay . – Jrapa86 Jun 25 '20 at 02:46
  • You can see this https://stackoverflow.com/a/15268692/7528659, which it offered a solution to the same problem. – H M Jun 25 '20 at 03:04
  • You can see this [enter link description here](https://stackoverflow.com/a/15268692/7528659), which it offered a solution to your problem. – H M Jun 25 '20 at 03:06
  • (I appreciate it is frustrating to be downvoted when one is new - it happens. However, please do not add voting advice into your posts - it is not of interest to readers, and gives them irrelevant material to read. Keep posts succinct if you can. I don't recommend it, but you can add thoughts about voting in the comments.) – halfer Jun 25 '20 at 11:26
  • okay, sorry about that! – Jrapa86 Jun 25 '20 at 12:15

4 Answers4

1

You said json object? as in it's not an array? Anyway, if that's the case you need to build the for loop around the property keys, not index values, like so:

const yourObj = {one: {a: 'a', b: 'b'}, two: {a: 'a', b: 'b'} }

const keys = Object.keys(yourObj);

for (let i = 0; i < keys.length; i ++) {
    let a = yourObj[keys[i]].a
    let b = yourObj[keys[i]].b

    console.log(a,b)
}

Edit: rewrote your object

const objt = {
    "onShift": {
        "fastTrack1": {
            "name": "Bob, bob",
            "shift": "7a-7p",
            "service": "Fasttrack",
            "spectra": "722413",
            "office": "",
            "cell": ""
        },

        "fastTrack2": {
            "name": "Bill, Bill",
            "shift": "7a-7p",
            "service": "Fasttrack2",
            "spectra": "54827",
            "office": "",
            "cell": "123-456-9090"
        },
      
        "incoming": {
            "incoming_fastTrack1": {
                "name": "Billy, Bob",
                "shift": "7p-7a",
                "service": "Fasttrack",
                "spectra": "54821",
                "office": "",
                "cell": "123-456-8909"
            },

            "incoming_fastTrack2": {
                "name": "Funny, Bob",
                "shift": "7p-7a",
                "service": "Fasttrack2",
                "spectra": "3478",
                "office": "",
                "cell": ""
            },
      
            "shiftEnd": {
                "ended_E_MD": {
                    "name": "Kissy Bob",
                    "shift": "7a-3p",
                    "service": "Area E",
                    "spectra": "3281",
                    "office": "",
                    "cell": "123-456-12345"
                },

                "ended_D_MD": {
                    "name": "funky bob",
                    "shift": "7a-3p",
                    "service": "Area D",
                    "spectra": "0003",
                    "office": "",
                    "cell": ""
                },

                "ended_DE_MD": {
                    "name": "Jimmy, Bob",
                    "shift": "10a-6p",
                    "service": "Area D-E",
                    "spectra": "0002",
                    "office": "",
                    "cell": ""
                },

                "ended_Tr_MD": {
                    "name": "Jim, Bob",
                    "shift": "8a-4p",
                    "service": "Triage",
                    "spectra": "0001",
                    "office": "",
                    "cell": ""
                }  
            }
        }
    }
}
Pavlos Karalis
  • 2,893
  • 1
  • 6
  • 14
  • After looking at your answer and reviewing my code I realize that I mistook my JSON as a nested object, when in fact it is an array. This leads me to a new question: How do I dynamically create a nested object such that it contains all of the listings? When I try it, only the single first iteration shows up. I cant seem to figure out how to create a nested object with multiple objects within it. – Jrapa86 Jun 25 '20 at 12:15
  • I think your nesting is likely not organized in the way you want it to be (there are still syntax errors occurring). I suggest drawing a tree diagram of the object hierarchy and then carefully rewrite the nesting to match. – Pavlos Karalis Jun 25 '20 at 17:46
  • I rewrote the nesting; was the intended hierarchy to have onShift as a single property in the root layer, followed by fastTrack1, fastTrack2, and incoming in the 1st nested layer, followed by incoming_fastTrack1, incoming_fastTrack2, shiftEnd, followed by ended_E_MD, ended_D_MD, ended_Tr_MD, ended_DE_MD, and ended_Tr_MD? – Pavlos Karalis Jun 25 '20 at 18:02
1

Here's a real clean way with rubico

const data = {
  "onShift": {
    "fastTrack1": { "name": "Bob, bob", "shift": "7a-7p", "service": "Fasttrack", "spectra": "722413", "office": "", "cell": "" },
    "fastTrack2": { "name": "Bill, Bill", "shift": "7a-7p", "service": "Fasttrack2", "spectra": "54827", "office": "", "cell": "123-456-9090" },
  },
  "incoming": {
    "incoming_fastTrack1": { "name": "Billy, Bob", "shift": "7p-7a", "service": "Fasttrack", "spectra": "54821", "office": "", "cell": "123-456-8909" },
    "incoming_fastTrack2": { "name": "Funny, Bob", "shift": "7p-7a", "service": "Fasttrack2", "spectra": "3478", "office": "", "cell": "" },
  },
  "shiftEnd": {
     "ended_E_MD": { "name": "Kissy Bob", "shift": "7a-3p", "service": "Area E", "spectra": "3281", "office": "", "cell": "123-456-12345" },
     "ended_D_MD": { "name": "funky bob", "shift": "7a-3p", "service": "Area D", "spectra": "0003", "office": "", "cell": "" },
     "ended_DE_MD": { "name": "Jimmy, Bob", "shift": "10a-6p", "service": "Area D-E", "spectra": "0002", "office": "", "cell": "" },
     "ended_Tr_MD": { "name": "Jim, Bob", "shift": "8a-4p", "service": "Triage", "spectra": "0001", "office": "", "cell": "" }
  },
}

const { map } = rubico

map(map(agent => {
  console.log(agent)

  const {
    name, spectra, shift, cell, off,
  } = agent

  // $("#dataTargetOnCall").append('<tr><td>'+name+'</td><td>'+service+'</td>...etc');
}))(data)
<script src="https://unpkg.com/rubico"></script>

Documentation for map

Disclaimer: I am the author of rubico

richytong
  • 2,387
  • 1
  • 10
  • 21
0

as the structure of your data is nested without logic, the best way is to use an intermediate table to reference your target elements

const data = 
  { onShift: 
    { fastTrack1: { name: 'Bob, bob',   shift: '7a-7p', service: 'Fasttrack',  spectra: '722413', office: '', cell: '' } 
    , fastTrack2: { name: 'Bill, Bill', shift: '7a-7p', service: 'Fasttrack2', spectra: '54827',  office: '', cell: '123-456-9090' } 
    , incoming: 
      { incoming_fastTrack1: { name: 'Billy, Bob', shift: '7p-7a', service: 'Fasttrack',  spectra: '54821', office: '', cell: '123-456-8909' } 
      , incoming_fastTrack2: { name: 'Funny, Bob', shift: '7p-7a', service: 'Fasttrack2', spectra: '3478',  office: '', cell: '' } 
      , shiftEnd: 
        { ended_E_MD:  { name: 'Kissy Bob',  shift: '7a-3p',  service: 'Area E',   spectra: '3281', office: '', cell: '123-456-12345' } 
        , ended_D_MD:  { name: 'funky bob',  shift: '7a-3p',  service: 'Area D',   spectra: '0003', office: '', cell: '' } 
        , ended_DE_MD: { name: 'Jimmy, Bob', shift: '10a-6p', service: 'Area D-E', spectra: '0002', office: '', cell: '' } 
        , ended_Tr_MD: { name: 'Jim, Bob',   shift: '8a-4p',  service: 'Triage',   spectra: '0001', office: '', cell: '' } 
        } 
      } 
    } 
  } 
const
  onShiftTarget =
    [ 'fastTrack1'
    , 'fastTrack2'
    , 'incoming/incoming_fastTrack1'
    , 'incoming/incoming_fastTrack2'
    , 'incoming/shiftEnd/ended_E_MD'
    , 'incoming/shiftEnd/ended_D_MD'
    , 'incoming/shiftEnd/ended_DE_MD'
    , 'incoming/shiftEnd/ended_Tr_MD'
    ]
    
for( let st of onShiftTarget)
  {
  let target = st.split('/').reduce((a,c)=>a[c], data.onShift)

  console.log( target.name, target.shift ,  target.service )
  }
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

After looking through all the answers and reviewing my code I realize that I mistook my JSON as a nested object, when in fact it is an array. This leads me to a new question:

How do I dynamically create a nested object such that it contains all of the listings? When I try it, only the single first iteration shows up.

I cant seem to figure out how to create a nested object with multiple objects within it.

Jrapa86
  • 129
  • 1
  • 10