# Accessing msg.payload Object of Objects with dynamic inner object names

**URL:** <https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742>\
**Category:** General\
**Created:** [16 March 2021 20:36 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742 "2021-03-16T20:36:42Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 20:36 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/1 "2021-03-16T20:36:42Z")

</div>

Hello everyone,

I have the following msg.payload object output:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/e/ce9fe77f64f61ce43fc3702f26834abc9369939d.png)  
where in the future, there will be numerous objects inside (not just 1063960).

I would like to iterate across the objects and access the ID field in each to check for a match to an ID I want. However, the problem is that the object name "1063960" is a placeholder here, and in the future, I will be making a change to the code that will make this number random, so I won't be able to predict it and use the simple:

```auto
 if (msg.payload["1063960"].ID == "1063960") 

```

So, my questions is: is there some kind of symbol that I can place in this if statement instead of ["1063960"] to indicate msg.payload["any"] and have node red iterate through the inner objects and check their ID field for the match?

I found the following way of doing what I want through a previous question in the forum here;

```auto
let values = Object.values(msg.payload);

var i;
for (i = 0; i < values.length; i++) {
  if (values[i].ID == "1063960")
{
    global.gender = values[i].Gender
    msg.payload = global.gender;
    return msg; 
}
}

```

But I am curious to see if there is a way to just say "any" and skip over a field in the msg.payload path as that would be great to learn.

Thank you for the help in advance!

Note: I am also aware of the split node, and have managed to achieve my goal using it as well, but I am just wondering about the possibility of using the msg.payload syntax when there is a part we don't know

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [16 March 2021 20:49 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/2 "2021-03-16T20:49:09Z")

</div>

You can simply walk the object properties. Here is one way:

```javascript
Object.keys(msg.payload).forEach( key => {
    if ( msg.payload[key].id === '1063960' ) {
        ....
    }
})

```

---

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 20:58 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/3 "2021-03-16T20:58:58Z")

</div>

Oh thank you!  
That seems like it will do exactly what I need, but for some reason I am getting the error  
""TypeError: Cannot read property 'ID' of undefined""

This is the code in my function now:

```auto
Object.keys(msg.payload).forEach( key => {
    if (msg.payload[key].ID == "1063960" ) {
        global.gender = msg.payload[key].Gender
        msg.payload = global.gender;
        return msg; 
    }
})

```

And the msg.payload going into it was:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/7/47ce4781c09f69803bf31b2560486c1a1fd2a126.png)

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [16 March 2021 21:06 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/4 "2021-03-16T21:06:53Z")

</div>

Add a `node.warn(Object.keys(msg.payload))` statement above the forEach line to see what you are actually getting there.

---

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 21:14 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/5 "2021-03-16T21:14:02Z")

</div>

I placed that as instructed and received this:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/1/c11eef453173fe5197394f0e42b78354e0de7010.png)

Then, I placed a `node.warn(msg.payload[key])` right before the if and received these 2 outputs:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/f/7fcb905c173205b158f932448672046f8b07afce.png)

After that comes the error

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [16 March 2021 21:23 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/6 "2021-03-16T21:23:21Z")

</div>

> [@Huda](#):
>
> ```auto
> Object.keys(msg.payload).forEach( key => {
> if (msg.payload[key].ID == "1063960" ) {
> global.gender = msg.payload[key].Gender
> msg.payload = global.gender; // <- you are changing the msg.payload while iterating it 
> return msg; 
> }
> })
> 
> ```

That way the next iteration has payload which does not have any ID property

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [16 March 2021 21:27 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/7 "2021-03-16T21:27:49Z")

</div>

That is what I thought, because msg.payload is being overwritten, but there is also a `return msg` there which means that it should have returned immediately following inspecting the first element, so it should never have got to the second element.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [16 March 2021 21:29 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/8 "2021-03-16T21:29:31Z")

</div>

NO.You can't break the forEach

[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/Array/forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [16 March 2021 21:33 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/9 "2021-03-16T21:33:29Z")

</div>

Oh you are right, it is a `forEach` not a `for in`. I was concentrating on what was inside instead of what was doing the iteration.  
So yes, you are correct, it is the fact that msg.payload is being overwritten that is the problem.

---

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 21:59 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/10 "2021-03-16T21:59:39Z")

</div>

Thank you all so much for the help!!  
I replaced the `forEach` with a `for in` as suggested and it seems to be working perfectly now as far as I can tell. I will leave the final solution here in case this is needed by someone in the future:

````auto
for (var key in msg.payload){
    if (msg.payload[key].ID == "1063960" ) {
        global.gender = msg.payload[key].Gender
        msg.payload = global.gender;
        return msg; 
    }
}```
````

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [16 March 2021 22:02 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/11 "2021-03-16T22:02:59Z")

</div>

So you are looking for single match and send out the value of Gender property of that found object.

```auto
var needle = "1234"
var o = Object.keys(msg.payload).find(e => msg.payload[e].ID == needle)
msg.payload = msg.payload[o].Gender
return msg;

```

But if not found

```auto
var needle = 1234
var o = Object.keys(msg.payload).find(e => msg.payload[e].ID == needle)

msg.payload = o ? msg.payload[o].Gender : "Not found" // may be undefined if Gender propery does not exist

return msg;

```

---

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 22:27 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/12 "2021-03-16T22:27:48Z")

</div>

Yes exactly, thank you for the alternative method, this also seems to work great! (is there a way to mark 2 answers as the solution to a thread?)

I'm wondering what the difference between the one you first posted (using e =\> e) and the one here with msg.payload? they both seemed to work for me

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [16 March 2021 22:29 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/13 "2021-03-16T22:29:15Z")

</div>

I was wrong on that, I got result but false positive and didn't check.  
As the object name and ID are same (don't know is this always the case) the result is there but you wanted to check the ID property of every possible object (until first match)

---

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 22:44 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/14 "2021-03-16T22:44:21Z")

</div>

Oh that makes sense, thank you! I was confused because I was still getting the correct output despite trying an ID different than the name, but I just tried again and it gave the wrong answer, you're right; I must have done something differently the first time.

One more thing, please: `msg.payload = o ? msg.payload[o].Gender : "Not found" ` is meant to make the value "Not found" if it was undefined, right? because I am still receiving undefined output even after deleting the "Gender" field from the object 🤔 (It doesn't really matter to me as I have a "default" in the rest of my code, but just curious of the new syntax, sorry for the trouble!)  
This is the object where there is no Gender:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/1/41f8b37edcee434284b6301c1c55143e07d10778.png)

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [16 March 2021 22:52 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/15 "2021-03-16T22:52:31Z")

</div>

> [@hotNipi](#):
>
> `msg.payload = o ? msg.payload[o].Gender : "Not found"`

`Array.find()` does return found thing or `undefined` if nothing found.

So if the `o` is undefined, the `msg.payload` will be "Not found". In case of Gender property is missing, but the `o` is there, the output message payload will be `undefined` because of Gender does not exist.  
You can make another safety check to prevent such case.

---

<div class="post-metadata">

**Author:** ![Huda](https://avatars.discourse-cdn.com/v4/letter/h/7cd45c/32.png) [@Huda](https://discourse.nodered.org/u/Huda)\
**Post date:** [16 March 2021 22:54 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/16 "2021-03-16T22:54:11Z")

</div>

Ah, now it is all clear, thank you for the help 🙏

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [30 March 2021 22:54 UTC](https://discourse.nodered.org/t/accessing-msg-payload-object-of-objects-with-dynamic-inner-object-names/42742/17 "2021-03-30T22:54:53Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
