# JS: Pushing a new object into nested array-objects

**URL:** <https://discourse.nodered.org/t/js-pushing-a-new-object-into-nested-array-objects/12719>\
**Category:** General\
**Created:** [29 June 2019 11:34 UTC](https://discourse.nodered.org/t/js-pushing-a-new-object-into-nested-array-objects/12719 "2019-06-29T11:34:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![IoTPlay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/iotplay/32/40_2.png) [@IoTPlay](https://discourse.nodered.org/u/IoTPlay)\
**Post date:** [29 June 2019 11:34 UTC](https://discourse.nodered.org/t/js-pushing-a-new-object-into-nested-array-objects/12719/1 "2019-06-29T11:34:44Z")

</div>

I realise my problem is about understanding JS objects and arrays, I thus published this request in stackoverflow, but either I did not explain my problem correctly, or people do not understand why I need to have nested arrays and objects in Node-RED global context. No-one came back to offer real help, accept a person that thinks I should be making all nested arrays objects as well. for searching of the objects, I think they should still be arrays, I still do not have a solution. Here is what I have published in Stackoverflow [here](https://stackoverflow.com/questions/56726917/js-pushing-a-new-object-into-nested-array-objects)

* * *

I want to build a nested JS object, with an array, objects, arrays, etc, that will keep `homie` variables at different levels, closely resembling an easy storage structure to store and retrieve from the homie v3.0.1 [convention](https://homieiot.github.io/specification/). (I include some of my own structures into the JS objects & arrays, to improve readiblity & flexibility of the code, like grouping variables leading with an \_ underscore, so its not the same as the homie convention.)

The structure of the nested array / objects to be stored (in Node-RED global context - in JS object format), which I call the `homie Shadow`, (roughly `deviceID > nodeID > propertyID > propAttribute`, where devices, nodes, properties are all arrays of nested objects), `are`:

```javascript
[
  {"deviceID":
    {"_nodesArr":
        [
          {"nodeID":{
              "_propArr":
                [
                  {"propertyID":{"_propertyAttributes":
                    {"$attribute: attributeValue}}}
  } } ] } } ]
]

```

Below is an example dataset, which is stored in Node-RED in a global context variable called **homieShw** (short for homie Shadow):

```javascript
[
  {"ESP70":
      {"_nodesArr":
        [
          {"Light": {
              "_propArr":
              [
                {"Switch":{
                          "val":1,
                          "_propAttributes":{"$settable":true}
  } } ] } } ]
]

```

Now, heading to what I want to do, and my problem: The Javascript code, will receive messages from `mqtt`, to setup the above structure, but also update the variables, for instance, when the light of this ESP is switched off, the mqtt message looks as follows:

```auto
homie/ESP70/Light/Switch/1

```

Without needing to quote all the code I do, I have a specific problem - and that is to store into an array further down in the array hierarchy of the `homie Shadow` or variable `arrHomieShw` (retreived from the global context variable `homieShw`).

- To add an ESP device in the object's first array, the JS code, which tests if the deviceID is in the array already, and if not, adds a new element to the array **(this code works perfectly)**, from the incoming `mqtt message` above:

- The above function checks if the object exits, and if it does not, it pushes the new branch into arrHomieShw, this works perfectly.

- But now, I want to do same for the array at the next level of the hierarchy of `homieShw`. Thus, I want to write into the **node** array of objects, by checking if the nodeID exist for the deviceID, and if not, to push a new branch into it.

- The push command does not want to push into a hierarchy as explained above. This is what I have tried, (amongst others). The function `checkNodesArrCreated()` is called, with for instance with this mqtt message : `homie/ESP70/Air/Temperature/23`, after the variable `arrIdxDevice = getDeviceIdx();` - see this function also below.

- In the function `checkNodesArrCreated()`, the branch variable - which is pushed into the nested array `arrHomieShw` creates a new object, and does not branch below the same deviceID it found. I also tried to use variations of arrHomieShw.deviceID.push( branch ), but this also does not work.

How should I go about this?

```javascript
//-----------------------------------------------------------------------
function checkNodesArrCreated(){
    if(deviceID == Object.keys(arrHomieShw[arrIdxDevice])[0] ) {
        theObj = Object.values(arrHomieShw[arrIdxDevice][deviceID])
        if(theObj._nodesArr === undefined){
            branch = { _nodesArr:
                          {[nodeID]:{"_nodeAttributes": { [nodeAttribute]: val } } }
                      };
            arrHomieShw.push( branch );
        }
    }
}

//-----------------------------------------------------------------------
function getDeviceIdx(){
    for (i=0; i < arrHomieShw.length; i++) {
        if(deviceID == Object.keys(arrHomieShw[i])[0] ) {
            return i;
        }
    }
    return arrIdxDevice;
}

function getNodeIdx(deviceID, nodeID, arrIdxDevice, arrHomieShw){
    for (j=0; j < arrHomieShw[arrIdxDevice][deviceID]._nodesArr.length; j++) {
        if(nodeID == arrHomieShw[arrIdxDevice][deviceID]._nodesArr[j]){
            return j;
        }
    }
}

```

Could anybody help me out of the sink-hole I find myself in now?

---

<div class="post-metadata">

**Author:** ![tilleul](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/tilleul/32/78_2.png) [@tilleul](https://discourse.nodered.org/u/tilleul)\
**Post date:** [29 June 2019 14:11 UTC](https://discourse.nodered.org/t/js-pushing-a-new-object-into-nested-array-objects/12719/2 "2019-06-29T14:11:25Z")

</div>

Of course you might have a valid reason I'm unaware of, but it seems to me that if every Device has a unique DeviceID, every node within a device has a unique nodeID and every prop in a node has a unique property ID and then each attribute within is unique as well, then you could do without the arrays and it would be much simpler ...

```auto
{
"deviceID1": {
    "nodeID1": {
      "propertyID1": {
        "attribute1": value, 
        "attribute2": value,
         ...},
      "propertyID2": {
        "attribute1": value, 
        "attribute2": value,
         ...},
      ...},
    "nodeID2": {
       "propertyID1": { ... }, ...
   },
"deviceID2": { ...}
...
}

```

That way the message you receive from mqtt is actually mostly a path within your json ... you could split the string into an array using the "/" as a separator and check every level of the path for existence ...

---

<div class="post-metadata">

**Author:** ![tilleul](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/tilleul/32/78_2.png) [@tilleul](https://discourse.nodered.org/u/tilleul)\
**Post date:** [29 June 2019 14:14 UTC](https://discourse.nodered.org/t/js-pushing-a-new-object-into-nested-array-objects/12719/3 "2019-06-29T14:14:25Z")

</div>

sorry, I only realize now that my proposition seems to be equivalent to the answer you had on StackOverflow ... so this might not help ... but do you really have a valid reason to have arrays of objects ? the only reason I see is if the IDs are not unique (and in this case why call them IDs ?)

---

<div class="post-metadata">

**Author:** ![IoTPlay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/iotplay/32/40_2.png) [@IoTPlay](https://discourse.nodered.org/u/IoTPlay)\
**Post date:** [29 June 2019 22:05 UTC](https://discourse.nodered.org/t/js-pushing-a-new-object-into-nested-array-objects/12719/4 "2019-06-29T22:05:12Z")

</div>

I am now starting to doubt that I do need arrays... let me go test with objects only. But I am still wondering how would one do it.... thank you.
