Object to string issue

I need to change an object to string but I am not getting out the desired output.
My object is like this:
Schermata 2022-02-27 alle 15.44.19

I am using a function to stringify the object and strip out/replace the unwonted chars. For some reason I am not getting out the result I expect.

This is the function I am using:

var st=msg.payload;
output=JSON.stringify(st);
output=output.replace('{','');
output=output.replace('}','');
output=output.replace(',',':');
output=output.replace('"','');
msg.payload=output;
return msg;

I have tried replacing and removing the chars using the String Node and also using the above function (at present written step by step).

This is what I am getting out of the above function:
gpio17":1:"gpio13":0,"gpio27":1,"gpio22":0
This is what I would like to get out:
gpio13:0:gpio27:1:gpio17:1:gpio22:0

I am not sure why it is not working. Any help will be appreciated. Thanks.

[{"id":"cec70e3f10d1ba16","type":"function","z":"530a8a0554240fad","name":"","func":"var st=msg.payload;\noutput=JSON.stringify(st);\noutput=output.replace('{','');\noutput=output.replace('}','');\noutput=output.replace(',',':');\noutput=output.replace('\"','');\nmsg.payload=output;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":560,"wires":[["0a872df79f52613b"]]}]

This uses a Json node and a change node. It doesn't change the order of the input data to 13 , 27, 17, 22 though, not sure how to do that:

[{"id":"a43c6c2847cbebb0","type":"inject","z":"4be637d7361f36e2","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"gpio13\":0,\"gpio17\":1,\"gpio22\":0,\"gpio27\":1}","payloadType":"json","x":390,"y":120,"wires":[["0b14087deac59b0c","8ee058c9441eb18e"]]},{"id":"0b14087deac59b0c","type":"json","z":"4be637d7361f36e2","name":"","property":"payload","action":"","pretty":false,"x":530,"y":120,"wires":[["d0f55c14ebcc5ee2"]]},{"id":"b60ef364c5c0b191","type":"debug","z":"4be637d7361f36e2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":890,"y":120,"wires":[]},{"id":"d0f55c14ebcc5ee2","type":"change","z":"4be637d7361f36e2","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":",","fromt":"str","to":":","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"[{}\"]","fromt":"re","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":120,"wires":[["b60ef364c5c0b191"]]},{"id":"8ee058c9441eb18e","type":"debug","z":"4be637d7361f36e2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":80,"wires":[]}]

Alternatively if you want to continue using the function node:

var st=msg.payload;
let output = JSON.stringify(st);
output=output.replace('{','');
output=output.replace('}','');
output=output.replaceAll(',',':');
output=output.replaceAll('"','');
msg.payload=output;
return msg;

You need to set the g modifier to global replace, otherwise it just the first match

var st=msg.payload;
output=JSON.stringify(st);
output=output.replace(/\{|}|"/g,'');
output=output.replace(/,/g,':');
msg.payload=output;
return msg;

Or
you could do it in a change node with JSONata expression

$join($spread($zip($keys(payload), payload.*.$string($))),":")

Or If you want the same using Javascript, but don't wish to use regex

msg.payload = Object.entries(msg.payload).reduce((a,e,i,o) => {
   return a += e[0] + ":" + e[1] + (i < o.length-1 ? ":" : "")
},"")
return msg;

Regex is still quite new to me, but could you combine lines 3 and 4 in any way that would still work?

Thank you a million. This did work perfectly.

Yes it is possible with the replace as a call to a function , but seems a bit overkill. for one extra replace.

1 Like

Could you explain why the replacements of the ,'s for :'s has to be separate from the others? Is it because you want a different end result?

EDIT:
Never mind, It appears that the use of regex is only allowed for the first substring and not the replacement substring (meaning that you cannot set it to more than one end result).

Can you explain why you want that, it seems an unusual requirement?

I am sending data via MQTT. Since all the other data I am sending are strings, I thought to unify everything as string. Probably I don't need the name of the GPIO to be sent but I need to make sure they do not change position/order first.

If you pass the original object to the MQTT node it will convert it to a JSON string for you and send that. At the other end (if it is node-red) then again the MQTT node can convert it back to an object. If it isn't node-red then most toolchains can understand JSON strings in some way.

1 Like

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