Error parsing datas from 1st function node to a 2nd function node

#1

Hi,
can anybody explain me how to transfert the right datas from a 1st function node to a second function node?

I can't make it. The result is always: "{"error":{"code":400,"message":"Parse Error","errors":[{"domain":"global","message":"Parse Error","reason":"parseError"}]}}"

Here are the nodes:

[{"id":"383f4af8.c70816","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"42ac1eb2.53354","type":"inject","z":"383f4af8.c70816","name":"Invalid IWAP01+WIFI","topic":"","payload":"IWAP01190215V0000.0000N00000.0000E000.1061830323.8706000908000102,460,0,9520,3671,Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97#","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":141,"y":138.0000023841858,"wires":[["5fbfa8e5.d24398"]]},{"id":"5fbfa8e5.d24398","type":"function","z":"383f4af8.c70816","name":"AP01 split flag A/V","func":"// flag = A\n//IWAP01080524A2232.9806N11404.9355E000.1061830323.8706000908000102,460,0,9520,3671#\n// flag = V\n//IWAP01080524V0000.0000N00000.0000E000.1061830323.8706000908000102,460,0,9520,3671,Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97# \nlet answer = {}\nlet elements = msg.payload.replace('#','').split(\",\")                                                           // this gives an array containing the bits\n// elements[0] is the long string starting IWAP01\nanswer.command = elements[0].substr(0,6)\nlet dateStr = elements[0].substr(6,6)                                                                           // eg \"190215\" 15th Feb 2019\nanswer.date = new Date(Number(dateStr.substr(0,2))+2000, Number(dateStr.substr(2,2))-1, dateStr.substr(4,2))    // 080524 - date\nanswer.flag = (elements[0].substr(12,1))                                                               // true or false - A or V\nif (answer.flag === \"A\") {\n    let degreesN = Number(elements[0].substr(13,2))\n    let minutesN = Number(elements[0].substr(15,7))\n    let ns = elements[0].substr(22,1)                                                                           // N or S\n    let degreesE = Number(elements[0].substr(23,3))\n    let minutesE = Number(elements[0].substr(26,7))\n    let ew = elements[0].substr(33,1)                                                                           // E or W\n    answer.latitude = degreesN + minutesN/60                                                                    // 2232.9806N\n    if (ns === \"S\") answer.latitude = -answer.latitude\n    answer.longitude = degreesE + minutesE/60\n    if (ew === \"W\") answer.longitude = -answer.longitude                                                        // 11404.9355E\n}\n\nanswer.speedMoving = elements[0].substr(34,5)                                                                   // 000.1\nanswer.angleDirection = elements[0].substr(45,6)                                                                // 323.87\nanswer.signalStrength = elements[0].substr(51,3)                                                                // 060\nanswer.satellites = elements[0].substr(54,3)                                                                    // 009\nanswer.batteryLevel = elements[0].substr(57,3)                                                                  // 080\n// LBS datas\nanswer.mobileCountryCode = elements[1]                                                                          // 460\nanswer.mobileNetworkCode = elements[2]                                                                          // 0\nanswer.locationAreaCode = elements[3]                                                                           // 9520       \nanswer.cellId = elements[4]                                                                                     // 3671\n// WIFI bases only with flag = V\nlet i;\nanswer.wifiAccessPoints = []\n    if (answer.flag === \"V\") {\n        let wifiAccessPointsStrings = elements[5].split(\"&\")\n        let j;\n        for (j = 0; j < wifiAccessPointsStrings.length; j++) {\n            let baseElements = wifiAccessPointsStrings[j].split(\"|\")\n            answer.wifiAccessPoints.push({ ssid: baseElements[0], macAddress: baseElements[1], signalStrength: baseElements[2] })  // Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97\n    }\n    // adjust baseCountwifiAccessPoints just in case the number actually there didn't match that expexted\n    answer.baseCountwifiAccessPoints = answer.wifiAccessPoints.length\n}\n\nmsg.payload = answer\nreturn msg","outputs":1,"noerr":0,"x":371.50000762939453,"y":137.80000686645508,"wires":[["2f8f4e66.0a5e02"]]},{"id":"2f8f4e66.0a5e02","type":"switch","z":"383f4af8.c70816","name":"Answer option","property":"payload.flag","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"V","vt":"str"}],"checkall":"true","repair":true,"outputs":2,"x":361.50000762939453,"y":169.00000190734863,"wires":[[],["24ed7be4.61d274","28e4a4b2.800f9c"]]},{"id":"28e4a4b2.800f9c","type":"function","z":"383f4af8.c70816","name":"MLS POSITION","func":"// Get positions from wifiAccessPoints\nvar dev_url = \"https://location.services.mozilla.com/v1/geolocate?key=test\";\nvar data =\n    {\n  \"considerIp\": \"false\",\n  \"wifiAccessPoints\": [\n    {\n      \"ssid\": \"msg.payload.flag.baseElements[0]\",\n\t  \"macAddress\": \"msg.payload.flag.baseElements[1]\",\n      \"signalStrength\": \"msg.payload.flag.baseElements[2]\"\n    }\n  ]\n};\nvar msg = {\n    \"method\" : \"POST\",\n    \"url\" : dev_url,\n    \"headers\" : {\n        \"Content-Type\": \"application/json\",\n    },\n    \"payload\" : JSON.stringify(data)\n};\n \nreturn msg\n","outputs":1,"noerr":0,"x":361.50000381469727,"y":206.80002784729004,"wires":[["d48eaba7.f5f6e8","5016f062.3e769"]]},{"id":"d48eaba7.f5f6e8","type":"http request","z":"383f4af8.c70816","name":"MOZILLA MLS REQUEST","method":"use","ret":"txt","url":"","tls":"","x":396.300048828125,"y":283.8000535964966,"wires":[["8538befd.aec8f","755c9912.f87368"]]},{"id":"755c9912.f87368","type":"http response","z":"383f4af8.c70816","name":"","statusCode":"","headers":{},"x":631.8000106811523,"y":322.60005378723145,"wires":[]},{"id":"8538befd.aec8f","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":649.8000106811523,"y":251.600004196167,"wires":[]},{"id":"5016f062.3e769","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":649.5000076293945,"y":208.80002784729004,"wires":[]},{"id":"24ed7be4.61d274","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":652.2399978637695,"y":175.4400053024292,"wires":[]}]
0 Likes

#2

Your second function node

    {
  "considerIp": "false",
  "wifiAccessPoints": [
    {
      "ssid": "msg.payload.flag.baseElements[0]",
	  "macAddress": "msg.payload.flag.baseElements[1]",
      "signalStrength": "msg.payload.flag.baseElements[2]"
    }
  ]
};

You shouldn't have the quotes around the msg.payload parts

0 Likes

#3

Thanks ukmoose, unfortunatly... still have this message after correcting :

function : (error)

"TypeError: Cannot read property '0' of undefined"

It is like I can get the good datas from the 1st node...

0 Likes

#4

Add a debug node direct to your 1st function node.

Can you see msg.payload.flag.baseElements[0]?

0 Likes

#5

no I can't... It is a wrong format of course.
I'm trying ot extract from the first node the result of : wifiAccessPoints: array[4]

Here is what I can see from the node 1:

25/02/2019 à 12:17:54node: 24ed7be4.61d274
msg.payload : Object
object
command: "IWAP01"
date: "2019-02-14T22:00:00.000Z"
flag: "V"
speedMoving: "000.1"
angleDirection: "323.87"
signalStrength: "060"
satellites: "009"
batteryLevel: "080"
mobileCountryCode: "460"
mobileNetworkCode: "0"
locationAreaCode: "9520"
cellId: "3671"
wifiAccessPoints: array[4]
0: object
ssid: "Home"
macAddress: "74-DE-2B-44-88-8C"
signalStrength: "97"
1: object
ssid: "Home1"
macAddress: "74-DE-2B-44-88-8C"
signalStrength: "97"
2: object
ssid: "Home2"
macAddress: "74-DE-2B-44-88-8C"
signalStrength: "97"
3: object
ssid: "Home3"
macAddress: "74-DE-2B-44-88-8C"
signalStrength: "97"
baseCountwifiAccessPoints: 4

0 Likes

#6

Have a read of this - https://nodered.org/docs/user-guide/messages

0 Likes

#7

Thanks. I did it... once again!

As this document is nearly Chinese for me and get more than hundreed lines with different directions and purpose, it does not help me more and it does not explain what to import in the second function node...

You could also tell me the solution is under my eyes ... as I don't know what I'm looking for.
I don't know if I need to import the name in the object, the complete object in the array, the complete array itself, anything else... :slight_smile: Anyway, there are errors...

I've already read this document 1 week ago...

0 Likes

#8

Hi @jycemea

the bit of the documentation that is specifically relevant to your question is this section: https://nodered.org/docs/user-guide/messages#understanding-the-structure-of-a-message

In particular, it describes the three buttons that appear when you hover over any message element - one of which will copy to you clipboard the full path to that message element.

Given you are asking how to reference the first element under the wifiAccessPoints array, you could click the appropriate button next to that very element and you can then paste that where you need it.

0 Likes

#9

Thanks knolleary for this precision... I did it without any better result as below :

var data =
{
"considerIp": "false",
"wifiAccessPoints": [
{
"ssid": payload.wifiAccessPoints[0].ssid,
"macAddress": payload.wifiAccessPoints[0].macAddress,
"signalStrength": payload.wifiAccessPoints[0].signalStrength
}
]
....

give me :

25/02/2019 à 14:38:55node: MLS POSITIONfunction : (error)

"ReferenceError: payload is not defined (line 8, col 15)"

for :

[{"id":"383f4af8.c70816","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"2f096f1d.1a7ee","type":"inject","z":"383f4af8.c70816","name":"Invalid IWAP01+WIFI","topic":"","payload":"IWAP01190215V0000.0000N00000.0000E000.1061830323.8706000908000102,460,0,9520,3671,Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97#","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":139,"y":179.19999313354492,"wires":[["7e177ddc.774134"]]},{"id":"7e177ddc.774134","type":"function","z":"383f4af8.c70816","name":"AP01 split flag A/else","func":"// flag = A\n//IWAP01080524A2232.9806N11404.9355E000.1061830323.8706000908000102,460,0,9520,3671#\n// flag = V\n//IWAP01080524V0000.0000N00000.0000E000.1061830323.8706000908000102,460,0,9520,3671,Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97# \nlet answer = {}\nlet elements = msg.payload.replace('#','').split(\",\")                                                           // this gives an array containing the bits\n// elements[0] is the long string starting IWAP01\nanswer.command = elements[0].substr(0,6)\nlet dateStr = elements[0].substr(6,6)                                                                           // eg \"190215\" 15th Feb 2019\nanswer.date = new Date(Number(dateStr.substr(0,2))+2000, Number(dateStr.substr(2,2))-1, dateStr.substr(4,2))    // 080524 - date\nanswer.flag = (elements[0].substr(12,1))                                                               // true or false - A or V\nif (answer.flag === \"A\") {\n    let degreesN = Number(elements[0].substr(13,2))\n    let minutesN = Number(elements[0].substr(15,7))\n    let ns = elements[0].substr(22,1)                                                                           // N or S\n    let degreesE = Number(elements[0].substr(23,3))\n    let minutesE = Number(elements[0].substr(26,7))\n    let ew = elements[0].substr(33,1)                                                                           // E or W\n    answer.latitude = degreesN + minutesN/60                                                                    // 2232.9806N\n    if (ns === \"S\") answer.latitude = -answer.latitude\n    answer.longitude = degreesE + minutesE/60\n    if (ew === \"W\") answer.longitude = -answer.longitude                                                        // 11404.9355E\n}\nif (answer.flag === \"V\") {\n    answer.latitude = 0\n    answer.longitude = 0\n}    \n    \nanswer.speedMoving = elements[0].substr(34,5)                                                                   // 000.1\nanswer.angleDirection = elements[0].substr(45,6)                                                                // 323.87\nanswer.signalStrength = elements[0].substr(51,3)                                                                // 060\nanswer.satellites = elements[0].substr(54,3)                                                                    // 009\nanswer.batteryLevel = elements[0].substr(57,3)                                                                  // 080\n// LBS datas\nanswer.mobileCountryCode = elements[1]                                                                          // 460\nanswer.mobileNetworkCode = elements[2]                                                                          // 0\nanswer.locationAreaCode = elements[3]                                                                           // 9520       \nanswer.cellId = elements[4]                                                                                     // 3671\n// WIFI bases only with flag = else\n// answer.wifiAccessPoints = elements[5]\nlet i;\nanswer.wifiAccessPoints = []\n    if (answer.flag === \"V\") {\n        let wifiAccessPointsStrings = elements[5].split(\"&\")\n        let j;\n        for (j = 0; j < wifiAccessPointsStrings.length; j++) {\n            let baseElements = wifiAccessPointsStrings[j].split(\"|\")\n            answer.wifiAccessPoints.push({ ssid: baseElements[0], macAddress: baseElements[1], signalStrength: baseElements[2] })  // Home|74-DE-2B-44-88-8C|97&Home1|74-DE-2B-44-88-8C|97&Home2|74-DE-2B-44-88-8C|97&Home3|74-DE-2B-44-88-8C|97\n    }\n    // adjust baseCountwifiAccessPoints just in case the number actually there didn't match that expexted\n    answer.baseCountwifiAccessPoints = answer.wifiAccessPoints.length\n}\n\nmsg.payload = answer\nreturn msg","outputs":1,"noerr":0,"x":363.50000762939453,"y":128,"wires":[["7b58e855.124b18"]]},{"id":"7b58e855.124b18","type":"switch","z":"383f4af8.c70816","name":"Answer option","property":"payload.flag","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"V","vt":"str"}],"checkall":"true","repair":true,"outputs":2,"x":374.49999237060547,"y":182.1999855041504,"wires":[["ddcfd3c.248d83"],["4d2400a.0baf7","33e3bb48.375134"]]},{"id":"ddcfd3c.248d83","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":632.2399978637695,"y":148.63999462127686,"wires":[]},{"id":"4d2400a.0baf7","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":631.2399978637695,"y":199.63999462127686,"wires":[]},{"id":"9484293b.809ce8","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":597.5000076293945,"y":239.00000381469727,"wires":[]},{"id":"33e3bb48.375134","type":"function","z":"383f4af8.c70816","name":"MLS POSITION","func":"// Get positions from wifiAccessPoints\nvar dev_url = \"https://location.services.mozilla.com/v1/geolocate?key=test\";\nvar data =\n    {\n  \"considerIp\": \"false\",\n  \"wifiAccessPoints\": [\n    { \n      \"ssid\": payload.wifiAccessPoints[0].ssid,\n\t  \"macAddress\": payload.wifiAccessPoints[0].macAddress,\n      \"signalStrength\": payload.wifiAccessPoints[0].signalStrength\n    }\n  ]\n};\nvar msg = {\n    \"method\" : \"POST\",\n    \"url\" : dev_url,\n    \"headers\" : {\n        \"Content-Type\": \"application/json\",\n    },\n    \"payload\" : JSON.stringify(data)\n};\n \nreturn msg\n","outputs":1,"noerr":0,"x":375.50000762939453,"y":241.00000381469727,"wires":[["e4614c86.28b93","9484293b.809ce8"]]},{"id":"e4614c86.28b93","type":"http request","z":"383f4af8.c70816","name":"MOZILLA MLS REQUEST","method":"use","ret":"txt","url":"","tls":"","x":470.30005645751953,"y":323.0000295639038,"wires":[["431ee23a.e4bbac","ba6c6cdc.23755"]]},{"id":"ba6c6cdc.23755","type":"http response","z":"383f4af8.c70816","name":"","statusCode":"","headers":{},"x":679.8000068664551,"y":322.8000297546387,"wires":[]},{"id":"431ee23a.e4bbac","type":"debug","z":"383f4af8.c70816","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":696.8000106811523,"y":383.8000297546387,"wires":[]}]
0 Likes

#10

should be msg.payload.wifiAccessPoints[0].ssid

0 Likes

#11

Nice!!! Did it...but errors with answer cause I used test datas. I'm going to try with real ones!

Thanks!!!

0 Likes

#12

In my first function node, I'm receiving an array of 4 objects... but it could be really more or really less (variable), it depends of scanning as in example below :

wifiAccessPoints: array[4]
0: object
1: object
2: object
3: object
baseCountwifiAccessPoints: 4

If I'm not importing the same qty of of objects in my second node, the answer is always coming back with errors... So, is there a way to create the values below, as many times as there are objects in the first node? ... here, there 4 objects...

{
    "macAddress": "valueA0",
    "signalStrength": valueB0,
 },
 {
    "macAddress": "valueA1",
    "signalStrength": valueB1,
 },
 {
    "macAddress": "valueA2",
    "signalStrength": valueB2,
 },
 {
    "macAddress": "valueA3",
    "signalStrength": valueB3,
 },

]
}

X number of objects.....

0 Likes

#13

Reading time ..
https://www.w3schools.com/js/js_loop_for.asp

0 Likes

#14

Do you just want to copy the wifiAccessPoints value into the new structure? The only difference I can see is you have left the ssid values behind.

0 Likes

#15

I'm sorry cause maybe the way I'm trying to describe the issue is not really clear... Now cause of you and hotNipi, I understood how to import the good values in node 2...

Here (in my 1 node), I have this :

wifiAccessPoints: array[2]
0: object
ssid: "Tenda_216900"
macAddress: "C8-3A-35-21-69-00"
signalStrength: "82"
1: object
ssid: "Cristi Net"
macAddress: "00-16-0A-1B-34-F2"
signalStrength: "84"

So in my second node I'm using to geolocate positions from WIFI bases, I will have :

...
"wifiAccessPoints": [
    {
        "macAddress": msg.payload.wifiAccessPoints[0].macAddress,
        "signalStrength": msg.payload.wifiAccessPoints[0].signalStrength,
    },
    {
        "macAddress": msg.payload.wifiAccessPoints[1].macAddress,
        "signalStrength": msg.payload.wifiAccessPoints[1].signalStrength,
    }

...

So imagine, I will have next time 10 differents objects (including macAddress and signalStrength values) in node 1... Of course, I will need to format my request with the 10 objects extracted values in node 2, right?
The problem is I never know how many objects are going to be created in node 1 next time... so I would like to create a rule, in node 2, to verify how many objects are created in the wifiAccessPoints array in node 1... and to send my request with the same number. If not, the answer will be always false...

0 Likes

#16

When sharing code/json/flows please make sure you use the 'preformatted text' button in the forum toolbar to make sure they are formatted properly.

To re-ask my previous question then, it looks very much like you want to copy the wifiAccessPoints object into this new message, but just leave the ssid property out. Is that right?

0 Likes

#17

I will.
So, yes, I need to copy the objects from wifiAccessPoints in node 2, in the same way they are actually formatted... as :

{
"macAddress": msg.payload.wifiAccessPoints[0].macAddress,
"signalStrength": msg.payload.wifiAccessPoints[0].signalStrength,
},
{
"macAddress": msg.payload.wifiAccessPoints[1].macAddress,
"signalStrength": msg.payload.wifiAccessPoints[1].signalStrength,
}
0 Likes

#18

So going back to the flow you shared at the start, your second function node could do:

var data =
    {
  "considerIp": "false",
  "wifiAccessPoints": msg.payload.wifiAccessPoints
};

You don't need to copy each element individually if you just want a copy of the array you already have.

0 Likes

#19

I think I can't... Node 2 has to be formatted exactly as Mozilla MLS API ask (Mozilla locating service) as it is in : https://mozilla.github.io/ichnaea/api/geolocate.html#api-geolocate-latest

A minimal example using a cell network:

{
    "cellTowers": [{
        "radioType": "wcdma",
        "mobileCountryCode": 208,
        "mobileNetworkCode": 1,
        "locationAreaCode": 2,
        "cellId": 1234567,
        "signalStrength": -60
    }]
}

A minimal example using only WiFi networks:

{
    "wifiAccessPoints": [{
        "macAddress": "01:23:45:67:89:ab",
        "signalStrength": -51
    }, {
        "macAddress": "01:23:45:67:89:cd"
    }]
}

With your modif, Mozilla MLS answer is :
"{"error":{"code":404,"message":"Not found","errors":[{"domain":"geolocation","message":"Not found","reason":"notFound"}]}}"

25/02/2019 à 17:53:20node: ba6c6cdc.23755msg : string[18]

"No response object"

That should really be formatted like this in node 2 :

.....................................................
{
"macAddress": msg.payload.wifiAccessPoints[0].macAddress,
"signalStrength": msg.payload.wifiAccessPoints[0].signalStrength,
},
{
"macAddress": msg.payload.wifiAccessPoints[1].macAddress,
"signalStrength": msg.payload.wifiAccessPoints[1].signalStrength,
}
..................

I really need to copy each element individually ... as many as they are

0 Likes

#20

So here is an example that will loop over the elements of msg.payload.wifiAccessPoints and for each one, push a new element into data.wifiAccessPoints.

var data = {
  "considerIp": "false",
  "wifiAccessPoints": []
};

msg.payload.wifiAccessPoints.forEach(function(wifi) {
   data.wifiAccessPoints.push({
      macAddress: wifi.macAddress,
      signalStrength: wifi.signalStrength
   });
});

I don't know if that's what you really need, but hopefully its a steer in the right direction.

0 Likes