# Object.assign() throws error!

**URL:** https://discourse.nodered.org/t/object-assign-throws-error/55378
**Category:** Developing Nodes
**Created:** [18 December 2021 08:10 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378 "2021-12-18T08:10:26Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [18 December 2021 08:10 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/1 "2021-12-18T08:10:26Z")

</div>

Hi All

I'm creating my first node in a while and I am using `Object.assign()` to set default values on a config object. For some reason this throws an error:

```auto
18 Dec 08:05:37 - [error] TypeError: Cannot read property 'handleError' of undefined
    at VirtualDimmerConstructor.Node.error (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:524:30)
    at /usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:210:26
    at Object.trigger (/usr/lib/node_modules/node-red/node_modules/@node-red/util/lib/hooks.js:149:13)
    at VirtualDimmerConstructor.Node._emitInput (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:196:11)
    at VirtualDimmerConstructor.Node.emit (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:180:25)
    at VirtualDimmerConstructor.Node.receive (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:479:10)
    at Immediate.<anonymous> (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/flows/Flow.js:814:52)
    at processImmediate (internal/timers.js:464:21)

```

The code in question is:

```auto
const defaultConfig = {
    longPressDelay: 80,
    updateInterval: 100,
    maxBrightness: 100,
    minBrightness: 0,
};
const nodeInit = (RED) => {
    function VirtualDimmerConstructor(partialConfig) {
        const config = applyConfigDefaults(partialConfig);
        RED.nodes.createNode(this, config);
        this.on('input', (msg, send, done) => {
            send({ payload: 'hi' });
            if (done) {
                done();
            }
        });
    }
    RED.nodes.registerType('virtual-dimmer', VirtualDimmerConstructor);
};
function applyConfigDefaults(config) {
    return Object.assign(Object.assign({}, defaultConfig), config);
}
module.exports = nodeInit;

```

`Object.assign()` has been available since node 4 so I can't see why this would blow up...

I imagine that some people might come back and say "that's not how you're supposed to deal with defaults". This question is not about what the code is doing (currently this is very bare bones and just to make sure I can get a node working in node-red) but about why `Object.Assign` doesn't work. It's a feature that I use quite a bit in my coding so doing without it would be a pain!

Thanks

---

<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: [18 December 2021 08:43 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/2 "2021-12-18T08:43:58Z")

</div>

I can't see an issue with object assign.

Out of curiosity...

Can you try changing the line to `Object.assign({}, defaultConfig, config)`

Secondly, try setting config without the helper function eg `const config = Object.assign({}, defaultConfig, partialConfig);`

Lastly, again, to satisfy my curiosity, could you rearrange the code to use the more common pattern e.g...

```auto
​module​.​exports​ ​=​ ​function​ ​(​RED​)​ ​{
  function VirtualDimmerConstructor(partialConfig) {
        const config = ...
  }
 
 
 RED.nodes.registerType('virtual-dimmer', VirtualDimmerConstructor);
}

```

---

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [18 December 2021 11:44 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/3 "2021-12-18T11:44:23Z")

</div>

I updated the code to:

```auto
const defaultConfig = {
    longPressDelay: 80,
    updateInterval: 100,
    maxBrightness: 100,
    minBrightness: 0,
};

module.exports = (RED) => {
    function VirtualDimmerConstructor(partialConfig) {
        const config = Object.assign({}, defaultConfig, partialConfig);
        RED.nodes.createNode(this, config);
        this.on('input', (msg, send, done) => {
            send({ payload: 'hi ' + config.longPressDelay });
            if (done) {
                done();
            }
        });
    }
    RED.nodes.registerType('virtual-dimmer', VirtualDimmerConstructor);
};

```

and get the same issue:

```auto
18 Dec 11:43:15 - [error] TypeError: Cannot read property 'handleError' of undefined
    at VirtualDimmerConstructor.Node.error (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:524:30)
    at /usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:210:26
    at Object.trigger (/usr/lib/node_modules/node-red/node_modules/@node-red/util/lib/hooks.js:149:13)
    at VirtualDimmerConstructor.Node._emitInput (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:196:11)
    at VirtualDimmerConstructor.Node.emit (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:180:25)
    at VirtualDimmerConstructor.Node.receive (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/nodes/Node.js:479:10)
    at Immediate.<anonymous> (/usr/lib/node_modules/node-red/node_modules/@node-red/runtime/lib/flows/Flow.js:814:52)
    at processImmediate (internal/timers.js:464:21)

```

🙁

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [18 December 2021 11:46 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/4 "2021-12-18T11:46:25Z")

</div>

> [@Roaders](#):
>
> `Object.assign`

Couple of things. Firstly, what version of node.js are you running?

Then, you don't need to assigns I don't believe, `Object.assign` will merge multiple objects.

And lastly, you need to be careful that `config` doesn't itself contain an object property because `Object.assign` only does shallow not deep copies.

---

<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: [18 December 2021 12:20 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/5 "2021-12-18T12:20:32Z")

</div>

> [@TotallyInformation](#):
>
> I don't believe, `Object.assign` will merge multiple objects

[Object.assign() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#merging_objects)

---

<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: [18 December 2021 12:23 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/6 "2021-12-18T12:23:34Z")

</div>

> [@Roaders](#):
>
> `module.exports = (RED) => {`

Can you try again one more indulgence - without the arrow function.

> [@Steve-Mcl](#):
>
> ```auto
> ​module​.​exports​ ​=​ ​function​ ​(​RED​)​ ​{
> function VirtualDimmerConstructor(partialConfig) {
> const config = ...
> }
>  
> RED.nodes.registerType('virtual-dimmer', VirtualDimmerConstructor);
> }
> 
> ```

---

<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: [18 December 2021 12:37 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/7 "2021-12-18T12:37:38Z")

</div>

Additionally, could you console.log the `partialConfig` object (before object.assign) and console.log `config` after object.assign

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [18 December 2021 13:38 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/8 "2021-12-18T13:38:03Z")

</div>

I think you misread my message 😀

---

<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: [18 December 2021 15:12 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/9 "2021-12-18T15:12:10Z")

</div>

AHH hahaha. Yep. I did 😂😂😂

---

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [20 December 2021 06:50 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/10 "2021-12-20T06:50:59Z")

</div>

I'm confused by @Steve-Mcl message. `Object.assign` can merge multiple objects... I must be missing something...

My intention here was to set default values for the node config. What I didn't realise was that I was effectively throwing away the entire node object and creating a new one that I was trying to assign property values to. Node red was unhappy about that (presubably as we were trying to give it a node object that it hadn't created and knew nothing about) and threw some error.

I presume that there is probably a map of node instances somewhere so my new object was not in it and stuff blew up.  
Now that I know what was going on I'll delete that code and write it a different way!!! 😃  
Thanks for the responses.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [20 December 2021 09:31 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/11 "2021-12-20T09:31:53Z")

</div>

You don't have to start with an empty object `{}`, you can start with an existing object if you prefer. But you can have as many other arguments to the function as you like and they will all be merged into the first listed object. However, `Object.assign` only checks the top-level of objects and does not do any merging below that level - it just overwrites. The MDN entry has the details.

With the config object, what normally happens in your node's .js file is that you apply each config entry to the node's `this` object manually. So the easiest way to do what you want is to check whether the config entries with defaults have a real value in config and if not, apply the default value. There are lots of examples in existing nodes including my own uibuilder nodes. It is a very common requirement.

---

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [20 December 2021 09:46 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/12 "2021-12-20T09:46:34Z")

</div>

yup, thanks. I wasn't looking for deep merging, I was only wanting to default the top level config properties.

The reason that it started with an empty object was because the actual code I wrote (in typescript) was:

`const config = {...defaultConfig, ...partialConfig};`

which typescript then turns into 2 Object.assigns to a new empty object.

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [20 December 2021 09:49 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/13 "2021-12-20T09:49:50Z")

</div>

> [@Roaders](#):
>
> `this.on('input', (msg, send, done) => {`

I'm pretty sure this is the cause of the error.

Node event handlers should not be defined as arrow functions as they don't get `this` defined properly.

Change into a proper function declaration and all should be well.

---

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [20 December 2021 09:55 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/14 "2021-12-20T09:55:12Z")

</div>

nope. It was the fact that was returning an incorrect node object to node red.  
All arrow functions do is mainting the current `this` value. If `this` is undefined or `bannana` that same value will be used. An incorrect `this` value won't kill the function.  
an arrow function is the same as: `myFunction.apply(this, someParam)`

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [20 December 2021 10:08 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/15 "2021-12-20T10:08:13Z")

</div>

> [@Roaders](#):
>
> All arrow functions do is mainting the current `this` value.

I know full well what arrow functions do.

There was a similar issue a while ago where the fix was to not use arrow functions. I assumed you were hitting the same thing.

A previous version of the Node code set a custom `this` context for the event handlers to deal with scoping function calls to individual messages. But looking through the code (bits of which I haven't touched for a year or more) I can see I was wrong and it doesn't do that anymore.

> [@Roaders](#):
>
> It was the fact that was returning an incorrect node object to node red.

What was wrong with it and how did you fix it? Given I can't see anything immediately wrong with the code you shared at the start, it would be helpful to know what you changed so we can spot it in the future.

---

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [20 December 2021 10:57 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/16 "2021-12-20T10:57:52Z")

</div>

The code that fixed it was along the lines of:

```auto
const nodeWithDefaults = Object.assign(node, defaultConfig);

```

rather than:

```auto
const nodeWithDefaults = Object.assign({}, node, defaultConfig);

```

In the first case we are retaining the same object instance for the node rather than returning a new node with a shallow copy of the old node's properties.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [20 December 2021 11:14 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/17 "2021-12-20T11:14:20Z")

</div>

> [@Roaders](#):
>
> `Object.assign(node, defaultConfig)`

Have you checked that? I think that would always end up with the defaults?

---

<div class="post-metadata">

### Author: ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)
#### Post date: [20 December 2021 12:40 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/18 "2021-12-20T12:40:11Z")

</div>

yes, you're right. I was trying to demonstrate what fixed the exception and in the process got the defaulting wrong.

So. Something like this:

```auto
const config = Object.assign(defaultConfig, partialNode); // all config properties have a value

const node = Object.assign(partialNode, config); // assign all config properties to node

```

---

<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: [18 February 2022 12:41 UTC](https://discourse.nodered.org/t/object-assign-throws-error/55378/19 "2022-02-18T12:41:06Z")

</div>

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