writefileSync versus Async

302 views
Skip to first unread message

Anand Setlur

unread,
Feb 1, 2016, 4:48:38 PM2/1/16
to Node-RED
I have a need to wait till the write of a json payload to a file is done before continuing with the flow where the next node in the flow is a shell script (invoked using exec) accesses the contents of that newly written file. 

What is the best way to do this -- use writefileSync which blocks till the file is written before proceeding to the next statement or 

prevent the function  from proceeding  by returning null until an writefile(asynchronous) with a callback indicates that writing is complete

Thanks

mfeb

unread,
Feb 1, 2016, 10:05:53 PM2/1/16
to Node-RED
Funny you ask -

I was just asked this by a colleague.

What's needed here is a File node that's not a "sink" node (one input, no output nodes).

One possibility for this is to use the node.js "fs" write function, from within a function node.

Add this to your settings.js (or equivalent) file:

    fs:require('fs'),

And then put this in in a function node:

 context.global.fs.writeFile('data.json', JSON.stringify(msg.payload), function (err) {
  if (err) {
      console.log(err);
      msg.payload = false
      }
    else {
      console.log('wrote data.json');
      msg.payload = true;    
      }
    });

return msg;

The wait for a callback is what makes this have a synchronous wait.

You can do other things like passing in the write location in, e.g., msg.fileURL. And you can change error handling to your preferred alternative (e.g., a separate output for errors).

Nicholas O'Leary

unread,
Feb 2, 2016, 4:16:09 AM2/2/16
to Node-RED Mailing List
That example code isn't quite right. The writeFile function completes asynchronously to the function returning at the end. So msg will be returned straightaway regardless of the result of the writeFile callback. You need to use node.send() within the callback:

 context.global.fs.writeFile('data.json', JSON.stringify(msg.payload), function (err) {
  if (err) {
      console.log(err);
      msg.payload = false;
      }
    else {
      console.log('wrote data.json');
      msg.payload = true;     
      }
    node.send(msg);
    });

return null;

--
http://nodered.org
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave C-J

unread,
Feb 2, 2016, 5:30:51 AM2/2/16
to node...@googlegroups.com
And if you want to be picky - you could use...
    node.error(err,msg);
and 
    node.log('wrote data.json');
the error would then be catch-able with the catch node...

Anand Setlur

unread,
Feb 2, 2016, 1:10:49 PM2/2/16
to Node-RED
Thanks for the responses --- the asynchronous write sample works !

Any plans to extend the FILE node functionality to not just be a sink node ?

Rajat Sud

unread,
Jun 11, 2016, 4:25:34 AM6/11/16
to Node-RED
It would be useful if the file, http and database nodes had two outputs - one which would work for parallel flows and one for synch flows. The first one would just relay the msg like it works right now and the other one could use a node.send with the callback results. This would allow newbies like me who still cannot get their head around async programming avoid mistakes of assuming that the node returns the value from the operation when it passes flow to the next node.
Reply all
Reply to author
Forward
0 new messages