# Error-circular - where is this coming from?

**URL:** https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114
**Category:** General
**Created:** [21 January 2019 20:37 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114 "2019-01-21T20:37:23Z")
**Posts on this page:** 14
**Page:** 3

<div class="post-metadata">

### Author: ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)
#### Post date: [23 January 2019 11:01 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/41 "2019-01-23T11:01:29Z")

</div>

> [@knolleary](#):
>
> We are _undeprecating_ it for this sort of use case.

![tgud1](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/c/c8ae1e3f695b807f62de768711f746b9f54e45cb.jpeg)

(Sorry, totally inappropriate.)

---

<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: [24 January 2019 15:53 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/42 "2019-01-24T15:53:08Z")

</div>

@knolleary @dceejay, I am still not clear whether there is any difference (from the users point of view) between using context.myvar and context.get/set() when used with the memory store. Can we have a definitive answer on this?

---

<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: [24 January 2019 15:54 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/43 "2019-01-24T15:54:57Z")

</div>

> [@Colin](#):
>
> I am still not clear whether there is any difference (from the users point of view) between using context.myvar and context.get/set()

When used with in-memory context store, I can't immediately think of a difference.

Until the user decides they want to start persisting their data and find they have to change all their code because they used the 'wrong' style of api.

---

<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: [24 January 2019 16:00 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/44 "2019-01-24T16:00:07Z")

</div>

10 seconds later... I can think of a difference when you look at flow context.

`flow.myvar` and `flow.set('myvar',123)` are accessing two _different_ `myvar` objects - you cannot inter-mix the two styles.

If you need to access that context value from any other non-Function node (such as Change node), then you must use `flow.get/set` in your Function nodes.

A value set by `flow.myvar` will _not_ be visible to other nodes that access context using the get/set functions.

---

<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: [24 January 2019 16:06 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/45 "2019-01-24T16:06:02Z")

</div>

> [@knolleary](#):
>
> A value set by `flow.myvar` will _not_ be visible to other nodes that access context using the get/set functions.

That is worth remembering, but the reason I am asking is that when I asked this earlier (post #21) Dave replied saying they were not the same, as recursive objects could not be saved using context.get/set even with memory store. Unless he misread my question.

---

<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: [24 January 2019 16:08 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/46 "2019-01-24T16:08:39Z")

</div>

We are just trying to give clear guidance of how context can/should be used.

It is much easier to say `context.get/set` should not be used for those sorts of objects rather than adding in all sorts of qualifiers of "except if you use _this_ type of context store".

Yes, technically, the memory store can be used for anything. But the worry is it leads a developer to start using it for things they don't realise is not portable to other context stores.

---

<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: [24 January 2019 16:19 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/47 "2019-01-24T16:19:48Z")

</div>

> [@knolleary](#):
>
> We are just trying to give clear guidance of how context can/should be used.

OK. Not sure you have completely succeeded 🙂  
Considering how unusual recursive objects actually are, I would have thought possibly it might be better to recommend always using get/set but just point out that persistent storage cannot be used for recursive objects so, of the stores provided by node-RED, only the memory store can be used for such objects.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [30 January 2019 13:44 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/48 "2019-01-30T13:44:16Z")

</div>

> [@hazymat](#):
>
> ... and was surprised nobody else made a really simple delay based number fader like this hence resorting to giving it a go myself. So any input is greatly appreciated.

I've found some spare time to build a general solution.

You don't need to understand the `code`, just install `node-red-contrib-dsm` from the Manage palette menu and import the flow from the dsm Wiki [Fade in out](https://github.com/cflurin/node-red-contrib-dsm/wiki/Fade-in--out).

---

<div class="post-metadata">

### Author: ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)
#### Post date: [30 January 2019 22:02 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/49 "2019-01-30T22:02:27Z")

</div>

Hi, I really like this. Two possible improvements, would you consider them?

1/ Currently you need to set msg.topic to start. Why is this required? It's useful to retain the msg.topic (passed into the input) for e.g. controlling lights on the correct circuit

2/ Is there a good way to set a "pre-delay"? e.g. wait x seconds after receiving the input before starting the fade? This is great for sleep timers. For example, "Alexa, set bedroom to sleep", this would give you 10 minutes of low light, then start to fade gently.

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [30 January 2019 22:12 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/50 "2019-01-30T22:12:47Z")

</div>

can't you use the default delay node for this pre-delay?

---

<div class="post-metadata">

### Author: ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)
#### Post date: [30 January 2019 22:18 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/51 "2019-01-30T22:18:14Z")

</div>

It's possible, although this would delay the first value from being sent (i.e. the start value). You could wire a change node in parallel, but then

a) the fader reset (stop) command wouldn't work. (unless you piped that through the delay as well, which is messy)  
b) you'd have to manually keep the change node's value in sync with the fader start value.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [31 January 2019 09:12 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/52 "2019-01-31T09:12:29Z")

</div>

> [@hazymat](#):
>
> 1/ Currently you need to set msg.topic to start. Why is this required? It's useful to retain the msg.topic (passed into the input) for e.g. controlling lights on the correct circuit

`msg.topic` is the default to trigger the dsm, so you can send `start` or `stop`. However the default can be overwritten for example:

```auto
    "triggerInput": "cmd",
    "stateOutput": "cmd",

```

Now you can trigger the dsm by:

```auto
msg.cmd = "start"
msg.cmd = "stop"

```

> [@hazymat](#):
>
> 2/ Is there a good way to set a "pre-delay"? e.g. wait x seconds after receiving the input before starting the fade? This is great for sleep timers. For example, "Alexa, set bedroom to sleep", this would give you 10 minutes of low light, then start to fade gently.

For your use case I've added an additional parameter:

```auto
{
    "initialdelay": 2000,
    "start": 0,
    "end": 1,
    "duration": 3000,
    "step": 100
}

```

Flow:

```auto
[{"id":"b3c0022e.f99bc","type":"dsm","z":"6ff0723.8c6b78c","name":"fade in/out","sm_config":"{\n \"triggerInput\": \"cmd\",\n \"stateOutput\": \"cmd\",\n \"currentState\": \"stopped\",\n \n \"states\": {\n \"stopped\": {\n \"start\": \"started\",\n \"stop\": \"stopped\"\n },\n \"started\": {\n \"fade_in\": \"fade_in\",\n \"fade_out\": \"fade_out\",\n \"stop\": \"stopped\"\n },\n \"fade_in\": {\n \"fade_in\": \"fade_in\",\n \"stop\": \"stopped\"\n },\n \"fade_out\": {\n \"fade_out\": \"fade_out\",\n \"stop\": \"stopped\"\n }\n },\n \"data\": {\n \"initialdelay\": 2000,\n \"start\": 0,\n \"end\": 1,\n \"duration\": 3000,\n \"step\": 100\n },\n \"methods\": {\n \"init\": [\n \"sm.tick = function(tran, msg) {\",\n \" timeout.id = setTimeout(function() {\",\n \" sm.text = 'fading ' + sm.data.duration + ' - ' + sm.data.actual;\",\n \" msg.payload = sm.data.actual;\",\n \" node.send(msg);\",\n \" resume(tran, msg);\",\n \" }, sm.data.step);\",\n \"};\",\n \"sta.fill = 'grey';\"\n],\n \"onBeforeTransition\": [\n \"if (typeof msg.payload.initialdelay !== 'undefined') sm.data.initialdelay = msg.payload.initialdelay;\",\n \"if (typeof msg.payload.start !== 'undefined') sm.data.start = msg.payload.start;\",\n \"if (typeof msg.payload.end !== 'undefined') sm.data.end = msg.payload.end;\",\n \"if (typeof msg.payload.duration !== 'undefined') sm.data.duration = msg.payload.duration;\",\n \"if (typeof msg.payload.step !== 'undefined') sm.data.step = msg.payload.step;\"\n],\n \"start\": [\n \"clearTimeout(timeout.id);\",\n \"timeout.id = setTimeout(function() {\",\n \" sm.data.delta = (sm.data.step / sm.data.duration) * Math.abs(sm.data.start - sm.data.end);\",\n \" sm.data.actual = sm.data.start;\",\n \n \" if (sm.data.end > sm.data.start) {\",\n \" sm.text = 'fade_in';\",\n \" resume('fade_in', msg);\",\n \" } else {\",\n \" sm.text = 'fade_out';\",\n \" resume('fade_out', msg);\",\n \" };\",\n \"}, sm.data.initialdelay);\",\n \"sm.text = 'initial delay ' + sm.data.initialdelay;\",\n \"msg.payload = sm.data.start;\",\n \"node.send(msg);\"\n],\n \"fade_in\": [\n \"if (sm.data.actual < sm.data.end) {\",\n \" sm.data.actual = Math.round((sm.data.actual + sm.data.delta) * 100) / 100;\",\n \" if (sm.data.actual > sm.data.end) {sm.data.actual = sm.data.end;};\",\n \" sm.tick('fade_in', msg);\",\n \"} else {\",\n \" resume('stop', msg);\",\n \"};\"\n],\n \"fade_out\": [\n \"if (sm.data.actual > sm.data.end) {\",\n \" sm.data.actual = Math.round((sm.data.actual - sm.data.delta) * 100) / 100;\",\n \" if (sm.data.actual < sm.data.end) {sm.data.actual = sm.data.end;};\",\n \" sm.tick('fade_out', msg);\",\n \"} else {\",\n \" resume('stop', msg);\",\n \"};\"\n],\n \"stop\": [\n \"sm.text = sm.currentState;\",\n \"clearTimeout(timeout.id);\"\n],\n \"onAfterTransition\": \"output = false;\",\n \"status\": {\n \"fill\": {\n \"get\": \"sm.currentState === 'stopped' ? 'grey': 'green';\"\n },\n \"shape\": \"dot\",\n \"text\": {\n \"get\": \"sm.text || sm.currentState;\"\n }\n }\n }\n}","x":490,"y":2200,"wires":[["4e43e7f0.d1eee8"]]},{"id":"5226bacb.b02654","type":"inject","z":"6ff0723.8c6b78c","name":"fade in","topic":"mytopic","payload":"{\"initialdelay\":2000,\"start\":0,\"end\":1,\"duration\":3000,\"step\":100}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":2200,"wires":[["a027285c.4bf7a8"]]},{"id":"de736c65.b889a","type":"inject","z":"6ff0723.8c6b78c","name":"fade out","topic":"mytopic","payload":"{\"initialdelay\":2000,\"start\":1,\"end\":0,\"duration\":5000,\"step\":500}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":2240,"wires":[["a027285c.4bf7a8"]]},{"id":"6820c9c9.829228","type":"inject","z":"6ff0723.8c6b78c","name":"stop","topic":"mytopic","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":2280,"wires":[["4ec1aed8.ae5"]]},{"id":"4e43e7f0.d1eee8","type":"debug","z":"6ff0723.8c6b78c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":650,"y":2200,"wires":[]},{"id":"a027285c.4bf7a8","type":"change","z":"6ff0723.8c6b78c","name":"cmd","rules":[{"t":"set","p":"cmd","pt":"msg","to":"start","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":2200,"wires":[["b3c0022e.f99bc"]]},{"id":"4ec1aed8.ae5","type":"change","z":"6ff0723.8c6b78c","name":"cmd","rules":[{"t":"set","p":"cmd","pt":"msg","to":"stop","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":2280,"wires":[["b3c0022e.f99bc"]]}]

```

---

<div class="post-metadata">

### Author: ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)
#### Post date: [8 February 2019 19:28 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/53 "2019-02-08T19:28:31Z")

</div>

@cflurin Hi, just implemented the fades using your latest code snippet. It's so much tidier and works like a charm. Thank you so much for your help!

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [8 February 2019 20:01 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/54 "2019-02-08T20:01:56Z")

</div>

@hazymat: You are welcome.

The latest version in the Wiki: [https://github.com/cflurin/node-red-contrib-dsm/wiki/Fade-in--out](https://github.com/cflurin/node-red-contrib-dsm/wiki/Fade-in--out)  
has an additional property `unit` so you can set milliseconds, seconds or minutes.

Remember to change the `triggerInput` from `topic` to `cmd` for your use case.

[Previous page](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114.md?page=2)
