# Trouble Converting JS Object

**URL:** https://discourse.nodered.org/t/trouble-converting-js-object/16699
**Category:** General
**Created:** [14 October 2019 15:20 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699 "2019-10-14T15:20:36Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![jstou](https://avatars.discourse-cdn.com/v4/letter/j/dfb087/32.png) [@jstou](https://discourse.nodered.org/u/jstou)
#### Post date: [14 October 2019 15:20 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/1 "2019-10-14T15:20:36Z")

</div>

Hi, I am having trouble in Node Red converting a JavaScript object to an array or format where I can manipulate the data. Below is what the object looks like, basically a single object "array" with data, where the keys (left hand side) are timestamps that continually change. I am reading these from a JSON file and converting all the info from the file to JS objects. How do I convert this "table" to an array or other format, so I can use the data (right hand side)? I am actually only interested in the last value in the table.

Thanks in advance!  
jstou

10‎/‎14‎/‎2019‎ ‎11‎:‎05‎:‎10‎ ‎AMnode: 803a9dad.98efb  
msg.payload : Object

object  
2019-10-04T10:36:34.4726616-04:00: 16  
2019-10-04T10:37:34.4726616-04:00: 17  
2019-10-04T10:38:34.4726616-04:00: 16  
2019-10-04T10:39:34.4726616-04:00: 24  
2019-10-04T10:40:34.4726616-04:00: 7  
2019-10-04T10:41:34.4726616-04:00: 14  
2019-10-04T10:42:34.4716544-04:00: 27  
2019-10-04T10:43:34.4706866-04:00: 27  
2019-10-04T10:44:34.4686451-04:00: 18  
2019-10-04T10:47:59.9528671-04:00: 29.053  
2019-10-04T10:53:05.2162999-04:00: 29.053  
2019-10-04T10:54:56.0889368-04:00: 29.053  
2019-10-04T10:56:20.0673513-04:00: 29.053  
2019-10-04T10:56:46.6303011-04:00: 29.053  
2019-10-04T10:57:12.9376103-04:00: 29.053

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [14 October 2019 15:24 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/2 "2019-10-14T15:24:41Z")

</div>

> [@jstou](#):
>
> I am reading these from a JSON file and converting all the info from the file to JS objects

Can you share the bit of the flow where you are doing this part? If you are only interested in the last value, then it would be far more efficient to do that as part of the flow reading the file. This is because a JavaScript Object has no order. To get the 'last' entry from the object, you'd have to get all of its keys (`Object.keys(msg.payload)`) then sort them to get them into date order and then use that to access the most recent.

It would be far better if you have the data in an array earlier in the flow, straight from the file, to just get the last line of the file.

---

<div class="post-metadata">

### Author: ![jstou](https://avatars.discourse-cdn.com/v4/letter/j/dfb087/32.png) [@jstou](https://discourse.nodered.org/u/jstou)
#### Post date: [14 October 2019 15:33 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/3 "2019-10-14T15:33:37Z")

</div>

Knolleary, what I have so far is the file input node reading in the JSON file contents, a JSON node converting all the data to JS objects, then I have individual function nodes to manipulate the different data in which I'm interested. In the function node, I tried to read in the last value of the table, but Node Red did not like this, so I have to read in the entire object, which gives me the entire table.

When you say "better if you have the data in an array earlier in the flow", are you saying before converting the JSON file contents into JS objects?

Thanks,  
jstou

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [14 October 2019 15:54 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/4 "2019-10-14T15:54:56Z")

</div>

> [@jstou](#):
>
> When you say "better if you have the data in an array earlier in the flow", are you saying before converting the JSON file contents into JS objects?

It depends. I asked if you could share the flow so we can see exactly what you are doing. Without knowing what format your data is in, or what you are doing with it, it's hard to give you specific advice.

So, please can you share:

1. an example of the file in which you are storing the data so we can see what format it is in
2. an export of the bit of your flow that reads the file and converts it to objects.

---

<div class="post-metadata">

### Author: ![jstou](https://avatars.discourse-cdn.com/v4/letter/j/dfb087/32.png) [@jstou](https://discourse.nodered.org/u/jstou)
#### Post date: [14 October 2019 17:46 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/5 "2019-10-14T17:46:18Z")

</div>

Ok I have attached the image of the part of the flow where I am reading in the JSON file. Below is the snippet from the JSON showing the "table" that I trying to work with:

{  
"Sites": [  
{  
"PastPowerMeasurements":{"2019-10-04T10:36:34.4726616-04:00":16,"2019-10- 04T10:37:34.4726616-04:00":17,"2019-10-04T10:38:34.4726616-04:00":16,"2019-10-04T10:39:34.4726616-04:00":24,"2019-10-04T10:40:34.4726616-04:00":7,"2019-10-04T10:41:34.4726616-04:00":14,"2019-10-04T10:42:34.4716544-04:00":27,"2019-10-04T10:43:34.4706866-04:00":27,"2019-10-04T10:44:34.4686451-04:00":18,"2019-10-04T10:47:59.9528671-04:00":29.053,"2019-10-04T10:53:05.2162999-04:00":29.053,"2019-10-04T10:54:56.0889368-04:00":29.053,"2019-10-04T10:56:20.0673513-04:00":29.053,"2019-10-04T10:56:46.6303011-04:00":29.053,"2019-10-04T10:57:12.9376103-04:00":29.053}  
}  
]  
}

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/8/814c6e82121ce6a3a877b2cac2a0e99c5881334f.png)

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [14 October 2019 17:56 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/6 "2019-10-14T17:56:25Z")

</div>

> I am actually only interested in the last value in the table.

In a function node you could use:

```auto
m = msg.payload.Sites[0].PastPowerMeasurements
last = Object.values(m)[Object.values(m).length - 1];
return {payload:last};

```

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [14 October 2019 18:01 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/7 "2019-10-14T18:01:50Z")

</div>

> [@bakman2](#):
>
> In a function node you could use:

Technically you shouldn't. Object.values and Object.keys do not make any guarantee as to the order of their results. You should not assume the last entry in their results is the 'last' object property. This is why i said you'd have to use Object.keys to get all the timestamps, then sort it to ensure the right order and only then get the last entry.

---

<div class="post-metadata">

### Author: ![jstou](https://avatars.discourse-cdn.com/v4/letter/j/dfb087/32.png) [@jstou](https://discourse.nodered.org/u/jstou)
#### Post date: [14 October 2019 18:43 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/8 "2019-10-14T18:43:56Z")

</div>

Thanks for your inputs. Let me try this and get back to you.

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [15 October 2019 06:59 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/9 "2019-10-15T06:59:34Z")

</div>

I should read. Learn something every day.

---

<div class="post-metadata">

### Author: ![kuema](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kuema/32/6542_2.png) [@kuema](https://discourse.nodered.org/u/kuema)
#### Post date: [15 October 2019 07:24 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/10 "2019-10-15T07:24:08Z")

</div>

Just for reference, if you need a key-value mapping with _guaranteed insertion order_, there is a Map implementation since ES6. I try to avoid using "plain old JS objects" for dictionary purposes.

> **[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)**
>
> The Map object holds key-value pairs and remembers the original insertion order of the keys.

---

<div class="post-metadata">

### Author: ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)
#### Post date: [15 October 2019 12:11 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/11 "2019-10-15T12:11:24Z")

</div>

There is a discussion of a (somehow) similar [use case in this topic](https://discourse.nodered.org/t/read-data-from-json-array/1938/40). The final solution for that case was like Nick suggested you now: generate an array from the object, sort the array by timestamp and finally take the last element of the array.

---

<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: [15 October 2019 12:30 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/12 "2019-10-15T12:30:25Z")

</div>

> [@jstou](#):
>
> I tried to read in the last value of the table,

Is the data you want always in the last line of the file? If so then pick up the complete file as a string, split it into an array by splitting at the end of line character, and take the last line of the array.

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [15 October 2019 12:37 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/13 "2019-10-15T12:37:34Z")

</div>

the file in node can produce multiple messages (one per line) - and they will be tagged with a msg.parts property... the last one should have a msg.parts.count i think (need to check) - but does mark the last one of the file somehow.

---

<div class="post-metadata">

### Author: ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)
#### Post date: [15 October 2019 13:05 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/14 "2019-10-15T13:05:42Z")

</div>

A switch node configured with the tail option is an elegant solution to filter the last spitted element of an array.

![tail-switch-node](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/b/bb372b918d69eb47292494a0e1c7b71f8887fbc9.png)

```auto
[{"id":"7c5f78ae.9c8718","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"13d4cec8.086321","type":"inject","z":"7c5f78ae.9c8718","name":"","topic":"","payload":"[1,2,3,4,5]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":180,"wires":[["a6d216cd.5a6cf8"]]},{"id":"a6d216cd.5a6cf8","type":"split","z":"7c5f78ae.9c8718","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":340,"y":180,"wires":[["77b37282.c1849c"]]},{"id":"58850c0a.a3ae64","type":"debug","z":"7c5f78ae.9c8718","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":710,"y":180,"wires":[]},{"id":"77b37282.c1849c","type":"switch","z":"7c5f78ae.9c8718","name":"","property":"payload","propertyType":"msg","rules":[{"t":"tail","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":510,"y":180,"wires":[["58850c0a.a3ae64"]]}]

```

---

<div class="post-metadata">

### Author: ![jstou](https://avatars.discourse-cdn.com/v4/letter/j/dfb087/32.png) [@jstou](https://discourse.nodered.org/u/jstou)
#### Post date: [15 October 2019 14:07 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/15 "2019-10-15T14:07:30Z")

</div>

So I found out that the data table/object is already pre-sorted when inserted into the JSON file. So I tried bakman's code and it worked! Thanks for the tip!

Thanks for the other suggestions, I will keep them in mind based on future implementations.

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [15 October 2019 15:30 UTC](https://discourse.nodered.org/t/trouble-converting-js-object/16699/16 "2019-10-15T15:30:00Z")

</div>

> [@knolleary](#):
>
> You should not assume the last entry in their results is the 'last' object property. This is why i said you'd have to use Object.keys to get all the timestamps, then sort it to ensure the right order and only then get the last entry.

I completely agree with Nick -- just because your test of this small dataset seems to work, I would still sort by timestamp and return the latest value...

Here is how I would do it with a JSONata expression:

```auto
payload.Sites.PastPowerMeasurements.(
    $latest := $keys()^(>$)[0];
    $lookup($, $latest)
)

```

And if i paste your data into the Expression tester inside my `change` node, here's what I get:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/3/31be9cb3a4d45a89662e9af242ede01fd165ec5d.png)

The key bit is to sort the timestamps _descending_, and take the first one in the list:  
`$latest := $keys()^(>$)[0];`

Then you can lookup the value that matches that key -- and viola!
