# Best practice for the msg object?

**URL:** <https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210>\
**Category:** Developing Nodes\
**Created:** [27 November 2023 03:04 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210 "2023-11-27T03:04:01Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [27 November 2023 03:04 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/1 "2023-11-27T03:04:02Z")

</div>

What is the recommendation for dealing with the msg object. In the on Input event we get the msg object. Typically we might only be interested in the payload, but the msg properties might have items that need to be passed along like the response object of the http node.

So do I:

let reply = { payload: myFunc()}  
send(reply)

or

msg.payload = myFunc();  
reply(msg)

---

<div class="post-metadata">

**Author:** ![TerryE](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/terrye/32/65423_2.png) [@TerryE](https://discourse.nodered.org/u/TerryE)\
**Post date:** [27 November 2023 05:02 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/2 "2023-11-27T05:02:29Z")

</div>

~~Perhaps you should start be carefully rereading the [Function Documentation](https://nodered.org/docs/user-guide/writing-functions). (I must have reread this a dozen times myself and still pick up subtleties on each reread).~~

> The returned message object does not need to be the same object as was passed in; the function can construct a completely new object before returning it.

~~However, there are sometimes when nodes (e.g.`split`) or your own function code wants to add additional properties to pass extra state / context to downstream nodes, so in general if your node emits a single message, then it is safer just to update the message properties and return the updated message at the end. This type of function can safely be used in `sequence` node, implementing an `HTTP Service` etc. And I use this a lot by adding `msg.state` if I am looping back through a helper `MySQL` or `HTTP Request` node or simply passing stuff to another function node downstream.~~

~~If you don't want to pass through properties then just build the message as the Function guide suggests.~~

~~Also note that you don't need to use `node.send()` to send multiple outputs, as the guide also describes how you can use 1 and 2 dimensional message arrays to send multiple messages to multiple outputs through a single `return msgArray;` Just build the message array as needed and return it on exit~~

~~In general you _ **only** _ need to use `node.send()` _ **if** _ your function does asynchronous processing, that is it uses asynchronous callback functions such as `setTimout()`, or **Promises** and/or the keywords `async`, `await`. If you have used these, then you do need to use `node.send()`. This being said, at a runtime level, your function code is wrapped by the Node-RED runtime as an `async function` so you do have the rich async feature set available if you do need it. There are lots of decent tutorials on YouTube and the wider Internet if you want to understand more about this.~~

~~If you do use `node.send()`, then the Node-RED runtimes will assume that your code is doing asynchronous processing, so in this case you should _always_ follow the last send by a `node.done()` so that the runtime knows that this execution instance is completed.~~

**PS**. I missed the `Developing Nodes` tag. This answer really relates to "Developing Functions" rather than Nodes. The differences are sufficient that this is misleading and the Q is better addressed by others. Sorry, my bad.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [27 November 2023 07:57 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/3 "2023-11-27T07:57:52Z")

</div>

Always _try_ to return the original msg.

Consider someone uses your node between the http-in and http-response - the msg MUST have the original properties In order for the endpoint to work. Same goes for the TCP and split/join nodes.

Also, a common/recommended pattern (a PURE ish pattern) is to pass all properties needed in a msg to a function/flow/link/subflow. By discarding the original message, a user of your node would have to resort to storing the msg (or it's properties that are important and necessary for downstream nodes) before passing the message through your node, then picking them up again afterwards. If your node is async, this pattern will eventually catch the user out when fast consecutive messages result in inconsistencies.

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [27 November 2023 07:59 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/4 "2023-11-27T07:59:10Z")

</div>

```auto
let reply = { payload: myFunc()}
return reply

```

would overwrite the whole object, therefore losing any response properties

```auto
msg.payload = myFunc();
return msg

```

would just overwrite payload, saving any response properties.

~~p.s have moved category as I don't think this is about developing a node. If I am wrong let me know and will reverse move.~~

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [27 November 2023 08:03 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/5 "2023-11-27T08:03:37Z")

</div>

@E1cid I was unsure to but for the following clues:

1. Was posted in #Developing Nodes

2. Speaks of the `.on('input'` event

> [@Stwissel](#):
>
> on Input event

1. Mentioned `send(...)`

> [@Stwissel](#):
>
> send(reply)

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [27 November 2023 08:05 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/6 "2023-11-27T08:05:15Z")

</div>

Missed that, cheers have returned to developing nodes

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [27 November 2023 11:24 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/7 "2023-11-27T11:24:35Z")

</div>

Hi all,

appreciate the replies. In my actual case I do use async processing, so send is needed. @TerryE thx for the pointer to `node.done()`. Which opens an interesting followup question. I do

```auto
fetch(someurl, options)
  .then(result => result.body) // A [readableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)
.then(body => body.pipeThrough(new TextDecoderStream())
       .pipeTo(streamToSend(msg, send))
.catch(e => node.error(e));

```

the fetch returns a chunked response so the streamToSend is called a few times...

```auto
const streamToSend = (returnMsg, send) => {
  let sequence = 0;
  return new WritableStream({
    write(data) {
      sequence++;
      send({ ...returnMsg, seq: sequence, payload: data });
    }
  });
};

```

How would I fit the `node.done()` into it?

P.S.: Node will be public soon

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [27 November 2023 11:52 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/8 "2023-11-27T11:52:10Z")

</div>

> [@Stwissel](#):
>
> the fetch returns a chunked response so the streamToSend is called a few times...
> 
> ```auto
> const streamToSend = (returnMsg, send) => {
> let sequence = 0;
> return new WritableStream({
> write(data) {
> sequence++;
> send({ ...returnMsg, seq: sequence, payload: data });
> }
> });
> };
> 
> ```
> 
> How would I fit the `node.done()` into it?

When the fetch is `done`

e.g.

- request
- receive part 1 of 3 -\> send
- receive part 2 of 3 -\> send
- receive part 3 of 3 -\> send
- done()

---

<div class="post-metadata">

**Author:** ![TerryE](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/terrye/32/65423_2.png) [@TerryE](https://discourse.nodered.org/u/TerryE)\
**Post date:** [27 November 2023 13:32 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/9 "2023-11-27T13:32:35Z")

</div>

Yup, logically the "done" is just another message; however

- It must be issued only once.
- It must be issued after all other messages have been sent
- In this case it is not forwarded to the next node, but instead it is used by the runtime to determine the node's execution, that is to turn its running state from true to false.

In the case of user functions, the runtime actually scans the function source when deploying it to determine whether the function is asynchronous. (See [10-function.js:L139](https://github.com/node-red/node-red/blob/a55554193bac2ee4997948c6a15dd752844cace4/packages/node_modules/%40node-red/nodes/core/function/10-function.js#L139)). Module writers are expected to understand and to follow the rules.

PS. I am not sure what your indenting of the first then function is supposed to imply. This is just a flat promise chain.

---

<div class="post-metadata">

**Author:** ![drmibell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/drmibell/32/8424_2.png) [@drmibell](https://discourse.nodered.org/u/drmibell)\
**Post date:** [27 November 2023 21:21 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/10 "2023-11-27T21:21:01Z")

</div>

> [@Stwissel](#):
>
> What is the recommendation for dealing with the msg object

"Best practice" is "first, do no harm." The documentation on [Creating Nodes](https://nodered.org/docs/creating-nodes/node-js) is pretty unambiguous about this:

> If the node is sending a message in response to having received one, it should reuse the received message rather than create a new message object. This ensures existing properties on the message are preserved for the rest of the flow.

The only issue I can see arises if your node uses specific properties or values (for example, `msg.topic`, `msg.reset`, or `msg._control`) as part of its logic. Passing these along could affect the operation of either other nodes that use these properties differently or other instances of your own node. So the choice of how these are passed along should be clearly documented or made options in the configuration dialog.

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [28 November 2023 05:13 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/11 "2023-11-28T05:13:40Z")

</div>

Thx for the hint. Turns out I had the done() in my wrapper code already

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [27 January 2024 05:14 UTC](https://discourse.nodered.org/t/best-practice-for-the-msg-object/83210/12 "2024-01-27T05:14:29Z")

</div>

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