0

Been delivered some confusing JSON data with a problem I haven't seen before.

The JSON is formatted similar to this structure:

[
  {
    "title": "Event",
    "start_date": "2022-08-20 15:00:00",
    "end_date": "2022-08-20 16:00:00",
    "branch": {
      "85": "branchname"
    },
    "room": {
      "156": "roomname"
    },
    "age_group": {
      "5": "Youth",
      "6": "Teen"
    }
  },
  {
    "title": "Event02",
    "start_date": "2022-08-20 15:00:00",
    "end_date": "2022-08-20 16:00:00",
    "branch": {
      "72": "branchname"
    },
    "room": {
      "104": "roomname02"
    },
    "age_group": {
      "5": "Youth",
      "6": "Teen"
    }
  }
]

I'm trying to pull roomname out of the data, but it's nested in an object that has a random index number. If I manually put in the index number, I can retrieve the data, but the number changes every entry.

If I can figure out how to retrieve the number and store it in a variable, then use it again, or just somehow wildcard to just show any child of any key under the parent node "room" it would work perfect, but I don't know of a way to do this in javascript.

I'm limited to vanilla javascript, no external libraries or jquery.

here is the code that will output correctly if I manually enter the index numbers, but it only works for a single entry.

<script>
    const url = 'example.json';
    fetch(url) 
        .then((response) => { 
            return response.json(); 
        }) 
        .then((json) => { 
            json.map(function(event) { 
                console.log(`${event.start_date}`);
                console.log(`${event.title}`);
                console.log(`${event.room[156]}`);
                return element;
            });
    }, 80);

</script>

EDIT: Forgot to point out, there is always only 1 entry in the "room" tag, but it's index is randomized, so if you just select the room tag it returns undefined or invalid. If I could wildcard the index so it just tries them all, or somehow retrieve the index number and store it in a variable, it would fix the issue.

7
  • roomname has a number suffix sometimes like roomname02, are you looking for a value which starts with the word roomname? Commented Aug 19, 2022 at 18:22
  • related: stackoverflow.com/questions/983267/… Commented Aug 19, 2022 at 18:25
  • Is it possible to get the data changed on the backend to something like {"room": { "number": 104, "name": "roomname02" } }? It would make life a little easier, and make a bit more sense. Commented Aug 19, 2022 at 18:27
  • @niceman The roomname is just an example. Something closer to the actual data is roomname is something like "Upper Level Conference Room 5" Commented Aug 19, 2022 at 18:30
  • 1
    @Andy I don't have any backend access, i've got what i've got. Commented Aug 19, 2022 at 18:31

5 Answers 5

1

I think this will work:

Here as you don't know the key so, instead of just guessing, you can use Object.values(JSONObjName) to get the list/array of values in that json.

Here I'm also using optional chaining (?.) to handle the case when the json has no key value pairs.

<script>
    const url = 'example.json';
    fetch(url) 
        .then((response) => { 
            return response.json(); 
        }) 
        .then((json) => { 
            json.map(function(event) {
                const roomName = Object.values(event.room)?.[0];
                console.log(`${event.start_date}`);
                console.log(`${event.title}`);
                console.log(`${roomName}`);
                return {...event, room: roomName};
            });
    }, 80);

</script>
Sign up to request clarification or add additional context in comments.

2 Comments

This did it! thank you so much! Only change I made is changed the const to a let as the value will change depending on the room name. I need to read up on Object.values, clearly a blindspot for me.
It might be a good idea to change that variable name "json" to "data" as it's no longer JSON. And don't forget to return data.map when you do otherwise that array is going nowhere. @Sam
0

As long as you always want the first key you can fetch it like this

room = event.room[Object.keys(event.room)[0]]

Comments

0

if you want to get just roomname, you could do Object.values(room)[0] or if you want the index and value you could go for Object.entries(room)[0]

2 Comments

TypeError: Cannot read properties of undefined (reading 'room') It sees the index value as it's randomized number, not 0, so it returns undefined if it's not the random value
Maybe made some progress, using the line: console.log(Object.values(${event.room})[0]); it returns an open bracket for each entry: [
0
arr?.map(({ room }) => {
    for(let [key, value] of Object.entries(room)) {
        console.log('Random Key : ',key)
        console.log('Roomname : ', value)
        console.log('Using random key : ',room[key])
    }
})

By this way you can find the value of room against the random key.

Or you can try this if it is more relevant to you.

arr.map(({ room }) => {
    for(let key of Object.keys(room)) {
        console.log('Random Key : ',key)
        console.log('Using random key : ',room[key])
    }
})

Comments

0

Since you may want to do this for branch as well, here's an alternative solution which uses the object key as a computed property name (aka "dynamic key") to get the value.

And since, in this example it's done more than once, I've added that to a function that you can call in the destructuring assignment.

const data=[{title:"Event",start_date:"2022-08-20 15:00:00",end_date:"2022-08-20 16:00:00",branch:{85:"branchname"},room:{156:"roomname"},age_group:{5:"Youth",6:"Teen"}},{title:"Event02",start_date:"2022-08-20 15:00:00",end_date:"2022-08-20 16:00:00",branch:{72:"branchname02"},room:{104:"roomname02"},age_group:{5:"Youth",6:"Teen"}}];

// Get first key from an object
function getKey(obj) {
  return Object.keys(obj)[0];
}

const out = data.map(obj => {
  
  // Destructure the object and call `getKey` with the
  // object to get its only key, and use that
  // as a computed property to get its value, which 
  // we then relabel e.g. `roomName`
  const {
    branch: { [getKey(obj.branch)]: branchName },
    room: { [getKey(obj.room)]: roomName },
    ...rest
  } = obj;
  
  // Now just return a new object with your new keys/values
  return { ...rest, branchName, roomName };

});

console.log(out);

Additional documentation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.