# Why does that dynamic selector select both spotlights?

**URL:** <https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610>\
**Category:** General\
**Tags:** function-node\
**Created:** [30 April 2024 10:25 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610 "2024-04-30T10:25:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![novski](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/novski/32/23243_2.png) [@novski](https://discourse.nodered.org/u/novski)\
**Post date:** [30 April 2024 10:25 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/1 "2024-04-30T10:25:48Z")

</div>

Hi  
I use a dynamic selector to pick my device in a flow object by name.  
But it changes the offset values of all devices.

```auto
let init = {
    "offset": 0
}
let spotlights = flow.get("spotlights") ?? flow.set("spotlights", {
    "spot1" : init,
    "spot2" : init
});

spotlights[msg.device].offset = msg.offset;
msg.payload = spotlights[msg.device];
return msg;

```

 ![Bildschirmfoto 2024-04-30 um 12.20.03](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/d/2d17f41845927a28cdd48d2d2f1028f1139473c1.png)

Test export:

```auto
[
    {
        "id": "96be0d97663c2db7",
        "type": "inject",
        "z": "cbf7f47c.caccc8",
        "name": "set spot2 offset",
        "props": [
            {
                "p": "device",
                "v": "spot2",
                "vt": "str"
            },
            {
                "p": "offset",
                "v": "15",
                "vt": "num"
            },
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 2940,
        "y": 4120,
        "wires": [
            [
                "1cde18b38154698e"
            ]
        ]
    },
    {
        "id": "1cde18b38154698e",
        "type": "function",
        "z": "cbf7f47c.caccc8",
        "name": "init flow.spotlights[device][offset]",
        "func": "let init = {\n \"dimm\": { \"value\": 0, \"channel\": 1 },\n \"nc1\": { \"value\": 0, \"channel\": 2 },\n \"nc2\": { \"value\": 255, \"channel\": 3 },\n \"nc3\": { \"value\": 0, \"channel\": 4 },\n \"nc4\": { \"value\": 0, \"channel\": 5 },\n \"temp\": { \"value\": 0, \"channel\": 6 },\n \"zoom\": { \"value\": 0, \"channel\": 7 },\n \"offset\": 0\n}\nlet spotlights = flow.get(\"spotlights\") ?? flow.set(\"spotlights\", {\n \"spot1\" : init,\n \"spot2\" : init\n});\n\nspotlights[msg.device].offset = msg.offset;\nmsg.payload = spotlights[msg.device];\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 3230,
        "y": 4100,
        "wires": [
            [
                "224767e32291753f"
            ]
        ]
    },
    {
        "id": "06811ce1a75b8c24",
        "type": "inject",
        "z": "cbf7f47c.caccc8",
        "name": "set spot1 offset",
        "props": [
            {
                "p": "device",
                "v": "spot1",
                "vt": "str"
            },
            {
                "p": "offset",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 2940,
        "y": 4080,
        "wires": [
            [
                "1cde18b38154698e"
            ]
        ]
    },
    {
        "id": "224767e32291753f",
        "type": "debug",
        "z": "cbf7f47c.caccc8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 3470,
        "y": 4100,
        "wires": []
    }
]

```

Why does that happen?  
NR: v2.1.6

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [30 April 2024 11:07 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/2 "2024-04-30T11:07:14Z")

</div>

> [@novski](#):
>
> `flow.get("spotlights")`

This is a reference, one of the pitfalls of javascript.

try it like

```auto
let spotlights = RED.util.cloneMessage(flow.get("spotlights")) ?? ...

```

---

<div class="post-metadata">

**Author:** ![novski](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/novski/32/23243_2.png) [@novski](https://discourse.nodered.org/u/novski)\
**Post date:** [30 April 2024 11:20 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/3 "2024-04-30T11:20:25Z")

</div>

> [@bakman2](#):
>
> `RED.util.cloneMessage(`

No, that does not store the offset value at all, in the flow.spotlight.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [30 April 2024 11:50 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/4 "2024-04-30T11:50:04Z")

</div>

> [@novski](#):
>
> ```auto
> let spotlights = flow.get("spotlights") ?? flow.set("spotlights", {
> "spot1" : init,
> "spot2" : init
> });
> 
> ```

In english it will be:  
let the thingy be even an object or if it is null or undefined then the function which stores that kind of object.

Break it apart and do required steps when needed:

1. Ask for object
2. If not found, create with initial values
3. modify if needed
4. store back after modifications
5. use as part of outgoing message.

---

<div class="post-metadata">

**Author:** ![novski](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/novski/32/23243_2.png) [@novski](https://discourse.nodered.org/u/novski)\
**Post date:** [30 April 2024 12:26 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/5 "2024-04-30T12:26:56Z")

</div>

> [@hotNipi](#):
>
> Break it apart and do required steps when needed:
> 
> 1. Ask for object
> 2. If not found, create with initial values
> 3. modify if needed
> 4. store back after modifications
> 5. use as part of outgoing message.

like this?

```auto
let init = {
    "dimm": { "value": 0, "channel": 1 },
    "nc1": { "value": 0, "channel": 2 },
    "nc2": { "value": 255, "channel": 3 },
    "nc3": { "value": 0, "channel": 4 },
    "nc4": { "value": 0, "channel": 5 },
    "temp": { "value": 0, "channel": 6 },
    "zoom": { "value": 0, "channel": 7 },
    "offset": 0
}
let spotlights = flow.get("spotlights");
if (typeof spotlights === 'undefined'){
    flow.set("spotlights", {
        "spot1" : init,
        "spot2" : init
    });
    spotlights = flow.get("spotlights");
};
spotlights[msg.device]["offset"] = msg.offset;
msg.payload = spotlights[msg.device];
return msg;

```

This has the exact same behaviour.  
It overwrites both instances of spotlight (spot1 and spot2) at the same time.

and `spotlights[msg.device].offset = msg.offset;`

does the same as well.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [30 April 2024 12:49 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/6 "2024-04-30T12:49:42Z")

</div>

> [@novski](#):
>
> ```auto
> flow.set("spotlights", {
> "spot1" : init,
> "spot2" : init
> });
> 
> ```

The problem you are seeing is because javascripts accesses objects by reference. The result is that spot1 and spot2 both point to the same init object. The result is that when you fetch that back from context and then modify, for example, spot1, you are actually modifying the original init object and so spot2 also changes. Try this

```auto
    flow.set("spotlights", {
        "spot1" : init,
        "spot2" : RED.util.cloneMessage(init)
    });

```

That creates a clone of init to be referenced by spot2

---

<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:** [14 May 2024 12:50 UTC](https://discourse.nodered.org/t/why-does-that-dynamic-selector-select-both-spotlights/87610/7 "2024-05-14T12:50:04Z")

</div>

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