# How to change the name of a config field without breaking old flows

**URL:** <https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476>\
**Category:** Developing Nodes\
**Created:** [27 August 2024 09:31 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476 "2024-08-27T09:31:07Z")\
**Posts on this page:** 20\
**Page:** 1

<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:** [27 August 2024 09:31 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/1 "2024-08-27T09:31:07Z")

</div>

In a contrib node I need to change the name of a field. Can anyone suggest how I go about doing that such that config from old nodes is updated to use the new field name automatically? It is ok if the user has to open each old one and save it again, but I don't want him to lose the existing field contents.

It is a dashboard 2 ui node (gauge classic) and I should have called the class field `className` so that the dashboard automatically picks it up.

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [27 August 2024 11:25 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/2 "2024-08-27T11:25:59Z")

</div>

Hi Colin,

I should be saying use semantic versioning 😉

But one way, is to check for both variants in the code behind.

```auto

const foo = config.newProp || config.oldProp

```

In the defaults section, keep them both, BUT only create an element for the new? But don’t make it required for a while

And when the config editor is opened  
(Will need to check if it’s already been set)

```auto
this.newProp = this.oldProp

```

I don’t develop for dashboard, so I maybe incorrect in the complexity

---

<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:** [27 August 2024 13:09 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/3 "2024-08-27T13:09:49Z")

</div>

> [@marcus-j-davies](#):
>
> I should be saying use semantic versioning

I do, but I want to avoid a breaking change if possible, and if not then to at least minimise the impact.

> [@marcus-j-davies](#):
>
> `const foo = config.newProp || config.oldProp`

Unfortunately there is no such code. Provided I get the field name right (className) then it is all handled by the core D2 code (server side at least).

> [@marcus-j-davies](#):
>
> And when the config editor is opened  
> (Will need to check if it’s already been set)
> 
> ```auto
> this.newProp = this.oldProp
> 
> ```

I thought of doing something like that, but, unfortunately, if I import an old config then it seems that (in onEditPrepare) `this.oldProp` is undefined. I guess because the field does not exist in the html file. Perhaps I need to keep the old field as a hidden field.

---

<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:** [27 August 2024 15:08 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/4 "2024-08-27T15:08:30Z")

</div>

> [@Colin](#):
>
> unfortunately, if I import an old config then it seems that (in onEditPrepare) `this.oldProp` is undefined

`oldProp` should only be undefined if you've allowed that as a valid thing in your previous version. And in that case, it shouldn't matter if you pass undefined to the new prop.

---

<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:** [27 August 2024 15:44 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/5 "2024-08-27T15:44:33Z")

</div>

> [@TotallyInformation](#):
>
> `oldProp` should only be undefined if you've allowed that as a valid thing in your previous version. And in that case, it shouldn't matter if you pass undefined to the new prop.

`oldProp` is the name of the field in the old config. If the node is updated to the new version then, preferably, it should pick up the oldProp and move it to the new one. Otherwise the old value will be lost, but in the config passed in to onEditPrepare the oldProp is undefined even if it has a value in the old config.

**Edit** I am testing this by importing a node from an instance of node-red running the old software, then opening the node in the new s/w. I presume that is a valid way of doing it.

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [27 August 2024 16:08 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/6 "2024-08-27T16:08:37Z")

</div>

Because oldProp should always be defined in `node.defaults` to access to the value. Just remove the `value` property.

---

<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:** [27 August 2024 16:14 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/7 "2024-08-27T16:14:55Z")

</div>

Ah, I missed out 1 thing of course - when you need to change variables like this, you need to keep the oldProp variable. You will need to leave that code in your html file until you can be certainly nobody has the old version any more and that everyone with the new version has refreshed their settings. Basically, you will find it hard to remove the old variable. Generally though, it doesn't really matter.

So rather than moving oldProp to newProp, just make sure that any oldProp value is copied to newProp if newProp does not contain a value.

---

<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:** [27 August 2024 16:39 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/8 "2024-08-27T16:39:55Z")

</div>

> [@GogoVega](#):
>
> Just remove the `value` property.

Did you mean, in defaults, where previously I had  
`oldProp: {value: ""}`  
to change that to  
`oldProp: {}`

I tried that and now oldProp does appear in the config keys, but it is still undefined when I import an old config and open the node. Do I also have to keep the html for it, but make it a hidden field?

---

<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:** [27 August 2024 16:52 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/9 "2024-08-27T16:52:51Z")

</div>

> [@Colin](#):
>
> Do I also have to keep the html for it, but make it a hidden field?

No, but you do need to keep it in defaults in the html file AND in the node definition in your runtime js.

---

<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:** [27 August 2024 19:54 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/10 "2024-08-27T19:54:56Z")

</div>

> [@TotallyInformation](#):
>
> in the node definition in your runtime js.

I am not sure exactly which code you are referring to.

---

<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:** [27 August 2024 20:34 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/11 "2024-08-27T20:34:22Z")

</div>

In the runtime:

```auto
/** 2) This is run when an actual instance of our node is committed to a flow
 * type {function(this:runtimeNode&senderNode, runtimeNodeConfig & senderNode):void}
 * @param {runtimeNodeConfig & tiDummyNode} config The Node-RED node instance config object
 * @this {runtimeNode & tiDummyNode}
 */
function nodeInstance(config) {
    // As a module-level named function, it will inherit `mod` and other module-level variables

    // If you need it - which you will here - or just use mod.RED if you prefer:
    const RED = mod.RED
    if (RED === null) return

    // @ts-ignore Create the node instance - `this` can only be referenced AFTER here
    RED.nodes.createNode(this, config)

    /** Transfer config items from the Editor panel to the runtime */
    this.name = config.name ?? ''
    this.topic = config.topic ?? ''

    /** Handle incoming msg's - note that the handler fn inherits `this` */
    this.on('input', inputMsgHandler)
}

```

The `config` parameter is what contains all of the definitions passed from your html file. You create a node instance from the config. Oddly, you have to then manually transfer the config to your node instance. Never been quite sure why `RED.nodes.createNode(this, config)` doesn't do that automatically. Most people assign `const node = this` and then use `node` but that isn't necessary really, I just use `this`.

`this` or `node` contains the data defined by the flow author when they deploy an instance of your node but it is the runtime code that actually maintains the data. If you miss out that assignment step, your node instances don't save any of the settings.

---

<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:** [27 August 2024 20:46 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/12 "2024-08-27T20:46:58Z")

</div>

> [@TotallyInformation](#):
>
> Oddly, you have to then manually transfer the config to your node instance

I don't have that, and if you look at the basic example in the docs then it doesn't either - [Creating your first node : Node-RED](https://nodered.org/docs/creating-nodes/first-node)

---

<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:** [27 August 2024 21:20 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/13 "2024-08-27T21:20:11Z")

</div>

Interesting, always something to learn! Just did a quick test. So I guess it does save - however, if you don't transfer the config to the node instance, you won't really be able to easily use it in the runtime. Most examples do do this. I guess I made an assumption.

You might need to share some more code then to try and find the issue.

---

<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:** [28 August 2024 20:50 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/14 "2024-08-28T20:50:02Z")

</div>

> [@TotallyInformation](#):
>
> if you don't transfer the config to the node instance, you won't really be able to easily use it in the runtime

I have just realised why I am confused. I have only been working with D2 ui nodes recently. Looking back at my non-ui nodes I see that I am doing exactly what you say. The difference with the ui nodes is that the server I haven't needed to access the config directly, it is pretty much all in the client side.

Back on the fundamental problem, I have realised that it probably isn't possible to rename the field without at least forcing the user to open and close all existing nodes following the update. I have also realised that I can keep the existing name and work around the issue with a really trivial change in the code, so I have done that instead.

Thanks to all who offered help.

---

<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:** [29 August 2024 00:27 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/15 "2024-08-29T00:27:30Z")

</div>

> [@Colin](#):
>
> I have only been working with D2 ui nodes recently.

For [some odd reason](https://flows.nodered.org/node/node-red-contrib-uibuilder), I find that I can't find a reason to work on D2 nodes. 😁

---

<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:** [29 August 2024 05:53 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/16 "2024-08-29T05:53:15Z")

</div>

Joking aside, it's a shame that you don't. Uibuilder is a fantastic bit of work and if it seamlessly integrated with db2 and the 2 bodies of work offered users enhanced features it would be win win for the community.

I have absolutely no idea what that looks like, entails or if is even possible as I have such little time these days to explore this. Sure I know you could use ifrsmes or link from one to the other, but I'm thinking tighter integration, reusable components?, providing "pages" that are available as a tab? More?

---

<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:** [29 August 2024 09:03 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/17 "2024-08-29T09:03:06Z")

</div>

> [@Steve-Mcl](#):
>
> and if it seamlessly integrated with db2 and the 2 bodies of work offered users enhanced features it would be win win for the community.

Honestly, it is more the other way around Steve. I've offered repeatedly to collaborate not only before D2 was announced but previously with flexdash as well. UIBUILDER has been around a lot longer than D2.

I've also previously tried to engage on standardising message schema's and you will note that I went out of my way recently to add the `msg,_client` schema to UIBUILDER v7.

Also, being totally honest, the recent and rather inaccurate blog post about D2 vs "ui-builder" (sic) didn't really make me feel all that welcome.

As someone who has been active in supporting Node-RED for over 10 years, I've ALWAYS tried to encourage joined up work as I know fully the value of it.

I remain open to any ideas people have about a more joined-up approach between UIBUILDER and D2.

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [29 August 2024 09:54 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/18 "2024-08-29T09:54:11Z")

</div>

> [@TotallyInformation](#):
>
> Also, being totally honest, the recent and rather inaccurate blog post about D2 vs "ui-builder" (sic) didn't really make me feel all that welcome.

I'm sorry to hear that Julian. The [article](https://flowfuse.com/blog/2024/08/comparing-dashboard-2-with-uibuilder/) was written based on your [original forum post](https://discourse.nodered.org/t/capability-comparison-between-uibuilder-and-dashboard-2/88847), and we even included the table you made in the blog post.

If there are inaccuracies, please do surface those (via DM, here, or even better [open an issue on our website repo](https://github.com/FlowFuse/website) and we will get those corrected)

I have been very grateful of your collaboration (e.g. `msg._client` was an excellent move for both libraries), and we are keen to continue that moving forward, e.g. FF explicitly investing in development time just so that UI Builder runs on FF Cloud.

---

<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:** [29 August 2024 10:01 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/19 "2024-08-29T10:01:57Z")

</div>

Thanks Joe, I will DM you when I get a chance to respond properly. Though I would point out that if someone searches for "node-red-contrib-ui-builder", they won't find anything since that is not the correct package name.

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [29 August 2024 16:35 UTC](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476/20 "2024-08-29T16:35:22Z")

</div>

Now now kids!

You're missing a trick! - a thing called Flash and Action Script? 🤭

(to add some humour 😄 )

-- ENDOFSPAM

[Next page](https://discourse.nodered.org/t/how-to-change-the-name-of-a-config-field-without-breaking-old-flows/90476.md?page=2)
