Message structure checking not working as I thought

Ok, sorry, but this is confusing me.

I've recently been down the message structure trip and have learnt a couple of things.

So, I get a message from openweathermap node.

The rain fall is given in the message as: msg.data.rain["1h"]
Well, that's what is seems like when it is raining in the place.

So it has now raised the problem/question if there is no rain.

That part of the message doesn't exist.

So I wrote this:

node.warn(msg.data.rain["1h"]);

var x = msg.data.rain["1h"];

node.warn(x);

(Just to be sure)

Nothing.

No undefined messages.... No messages at all.

Why?

If that part of the message doesn't exist, why am I not getting an undefined message from it?

Does the msg.data part exist?
Does the msg.data.rain part exist?

are you getting an error?

Perhaps you should check before accessing...


// disable this to avoid an error when data or data.rain are undefined
// node.warn(msg.data.rain["1h"]);  

//if msg.data && msg.data.rain are SOMETHING, 
//  then       set x to msg.data.rain["1h"]  
//  otherwise  set x to null
var x = (msg.data && msg.data.rain) ?  msg.data.rain["1h"] : null;

node.warn(x);

EDIT

A tip for when you use node.warn - it can be dificult to see what the node.warn is warning you about when its just a number. Also, when its an object, you dont get to expand it etc.

When doing node.warn, I always do this....

node.warn(["rain value",x])

And you can even do this....

node.warn( [ "check the msg object value for msg.data.rain.1h should be same as x",  msg,  x ] );

... and see both the msg and the item of interest in the same warn message at the same time (no more guessing which msg was used to get x)

1 Like

If there is no rain, msg.data.rain doesn't exist.

So I'm not sure that would work.

Got this working though.

if (msg.data.rain === undefined)
{
    msg.payload = "clear";
} else
{
    msg.payload = msg.data.rain["1h"];
}
return msg;

Sorry Steve,

I got a bit confused. But thanks for helping with checking the structure.

I'm guessing that the [1] part was not helping. So checking that the part before that existed seems to do the trick.

Yeah - and?

//if msg.data && msg.data.rain are SOMETHING, 
//  then       set x to msg.data.rain["1h"]  
//  otherwise  set x to null
var x = (msg.data && msg.data.rain) ?  msg.data.rain["1h"] : null;

^ do you not understand what that is doing? What happens is...

  • if msg.data is undefined - x gets set to null (or "clear" or whatever you want)
  • if msg.data is present BUT msg.data.rain is undefined - x gets set to null (or "clear" or whatever you want)
  • if msg.data is present AND msg.data.rain is present - x gets set to msg.data.rain["1h"]



Yes it will - you didnt try did you!



And what if msg.data is empty? You WILL get an error in your version!

No, I have never been good with that sort of stuff. So, no: I didn't try it. I don't understand how it works.

I may have to sit down and learn it one day, but it really just blows my socks off with the iterations (or what ever it is called.)

Back in 1980 I may have understood it but only if it was written in BASIC.

I'm guessing that if it exists, there will be a value. If there is no value, it is undefined.
As I have got two places showing rain and no rain and where there is no rain, the path/structure doesn't exist.

and I used msg.data.rain.... not just msg.data.

var x = (msg.data && msg.data.rain) ?  msg.data.rain["1h"] : null;

2 constructs exist her...

  1. ternary operator : something == a_value ? true_value: otherwise_value
    or in english : if something equals a_value return true_value otherwise return otherwise_value

  2. short circuits : (msg.data && msg.data.rain)

    • msg.data.rain will NOT be evaluated if msg.data is falsey

So again...

var x = (msg.data && msg.data.rain) ?  msg.data.rain["1h"] : "clear";
// if msg.data is undefined/null/false - set x to "clear" - STOP 
// if msg.data.rain is undefined/null/false - set x to "clear" - STOP 
// if msg.data && msg.data.rain are SOMETHING set x to msg.data.rain["1h"]  

Andrew - guessing is why you have so many problems.

In your version, if msg.data is undefined - your function node will throw an error.

why? - because you try to evaluate msg.data.rain

look at the first line of your "working" function...

if (msg.data.rain === undefined)

This will instantly throw an error if msg.data is missing.

where as the version i provided will NOT throw an error.


Any how, you crack on asking for answers then ignore them.

I pull the rain data like this if undefined it returns 0

[{"id":"ffc02d8f.5c58c8","type":"inject","z":"8d22ae29.7df6d","name":"","props":[{"p":"payload.ChargeState","v":"11","vt":"num"},{"p":"msg.data","v":"{\"coord\":{\"lon\":0.28,\"lat\":50.77},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"base\":\"stations\",\"main\":{\"temp\":285.29,\"feels_like\":283.19,\"temp_min\":284.26,\"temp_max\":285.93,\"pressure\":1000,\"humidity\":81},\"visibility\":10000,\"wind\":{\"speed\":2.68,\"deg\":279,\"gust\":7.15},\"rain\":{\"1h\":0.44},\"clouds\":{\"all\":87},\"dt\":1603706880,\"sys\":{\"type\":3,\"id\":2012607,\"country\":\"GB\",\"sunrise\":1603694438,\"sunset\":1603730684},\"timezone\":0,\"id\":2650497,\"name\":\"Eastbourne\",\"cod\":200}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":2140,"wires":[["1d751194.60f8de"]]},{"id":"1632356d.a64dc3","type":"inject","z":"8d22ae29.7df6d","name":"","props":[{"p":"payload.ChargeState","v":"11","vt":"num"},{"p":"msg.data","v":"{\"coord\":{\"lon\":0.28,\"lat\":50.77},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"base\":\"stations\",\"main\":{\"temp\":285.29,\"feels_like\":283.19,\"temp_min\":284.26,\"temp_max\":285.93,\"pressure\":1000,\"humidity\":81},\"visibility\":10000,\"wind\":{\"speed\":2.68,\"deg\":279,\"gust\":7.15},\"clouds\":{\"all\":87},\"dt\":1603706880,\"sys\":{\"type\":3,\"id\":2012607,\"country\":\"GB\",\"sunrise\":1603694438,\"sunset\":1603730684},\"timezone\":0,\"id\":2650497,\"name\":\"Eastbourne\",\"cod\":200}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":2200,"wires":[["1d751194.60f8de"]]},{"id":"1d751194.60f8de","type":"function","z":"8d22ae29.7df6d","name":"","func":"msg.rain = msg.data.rain || {\"1h\":0};\nmsg.rain = Object.values(msg.rain)[0];\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":2180,"wires":[["49952583.65b3fc"]]},{"id":"49952583.65b3fc","type":"debug","z":"8d22ae29.7df6d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":470,"y":2160,"wires":[]}]

Ok, I used the wrong word.

I have seen two places. When one place has rain, the path in the message payload exists.
If there is no rain, the path in the message payload doesn't.

So I guess that what I said is true: if there is rain, the path exists, and if there is no rain, the path doesn't.

By my original inclusion of the ["1"] messed up the checking.
Dunno why.
But if I only check the path to msg.data.rain and not msg.data.rain["1"] the check works.

I know in all my examples it was msg.data.rain and not msg.data.
So the rest of your reply is ..... void?

msg.data always exists in all tests / messages received from the node.
It is just msg.data.rain may not.

It isn't that I ignore answers.
It is more I ask a question and don't sit here/there expecting an answer.
I try to nut it out in the mean time myself.

I sometimes need to ask it on the forum to help myself get my head around the problem.
I'm sure I have mentioned this and declared it many times.

Sorry. It may not be a nice way, but it is the only way I seem to be able to get things done.

Yes that is fair enough. But I wanted to return Clear so in the field which says "Rain" it displays "Clear".

change value from 0 to clear in function node.

msg.rain = msg.data.rain || {"1h":"Clear"};
msg.rain = Object.values(msg.rain)[0];
return msg;

And that statement is why you have bugs as far as I am concerned.

Programmers should NEVER assume anything.

I can't prove that is true.
I am not that smart a programmer.
I admit that.

I can only say that all the messages comply (obey?) this theory.

So until it isn't disproved I can't see why it can't be true at this point.

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