# Using $.getJSON in oneditsave

**URL:** <https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051>\
**Category:** Developing Nodes\
**Created:** [10 October 2021 02:21 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051 "2021-10-10T02:21:37Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![chris.willing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/chris.willing/32/76579_2.png) [@chris.willing](https://discourse.nodered.org/u/chris.willing)\
**Post date:** [10 October 2021 02:21 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/1 "2021-10-10T02:21:37Z")

</div>

When closing the config editor, I'd like to automatically set one of the available fields based on what the user has selected in another field i.e. if a particular device has been selected, then I want to set an appropriate productid. In oneditsave, I use $.getJSON to retrieve an object which defines these (device/productid) and other relationships. On the basis of some console.logs, it all seems successful - even setting the value of the productid html node. However the updated setting is not remembered; on next opening of the config editor, the product id entry is unchanged.

If (just as a test) I set the productid's value to something arbitrary outside of $.getJSON's function (commented out in code below), that value sticks.

Based on the above, it looks like the config editor is closing before $.getJSON has had time to do its thing. Is there some way to wait until for $.getJSON to finish?

I'm already using $.getJSON to retrieve the same data in oneditprepare. Could I save it somewhere to reuse later in oneditsave so I don't have to run $.getJSON in on editsave?

Code is:

```auto
oneditsave: function () {
        // Generate PID list for this device
        var device_pids = [];
        var device_selected = $("#node-input-device").val() || "ANY";
        $.getJSON('xkeys/products', function(xdata) {
            //console.log("XXXX " + device_selected + ", " + JSON.stringify(xdata));
            var selected_device = xdata[device_selected];
            if (selected_device) {
                console.log("YYYY " + selected_device.hidDevices[0][0]);
                device_pids.push(selected_device.hidDevices[0][0]);

                $("#node-input-productid").val(device_pids[0].toString());
                console.log("ZZZZ " + $("#node-input-productid").val());
                this.productid = $("#node-input-productid").val();
            } else {
                console.log("NO selected_device");
            }
        });
        //$("#node-input-productid").val("qwerty");
        //console.log("AAAA " + $("#node-input-productid").val());
}

```

BTW I'm using an array to hold productid numbers because a device can involve more than one of them. For simplicity, the code above only applies the first available productid

---

<div class="post-metadata">

**Author:** ![chris.willing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/chris.willing/32/76579_2.png) [@chris.willing](https://discourse.nodered.org/u/chris.willing)\
**Post date:** [10 October 2021 05:44 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/2 "2021-10-10T05:44:02Z")

</div>

While waiting for advice on this, I tried saving the data in a hidden node in oneditprepare and was able to retrieve and use it successfully in oneditsave.

```auto
<div class="form-row">
    <input type="hidden" id="node-input-productstore">
</div>

```

Then in oneditprepare at the end of $.getJSON:

```auto
    $.getJSON('xkeys/products', function(product_data) {
        ....
        ....
        // Save the product data in a hidden node
        $("#node-input-productstore").val(JSON.stringify(product_data));
    }

```

Later:

```auto
oneditsave: function () {
    var product_data = JSON.parse($("#node-input-productstore").val());

    // Do something with product_data
    ....
    ....
}

```

That actually works quite well but I'm still keen to hear of better or more elegant solutions.

More to the point - although reusing saved data has worked in this case by removing the need to use $.getJSON, what about the more general case of calling any async function from within oneditsave? How should that be handled?

---

<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:** [10 October 2021 07:46 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/3 "2021-10-10T07:46:16Z")

</div>

There is currently no support for async actions in oneditsave that need to complete before the node is updated - it is simply not a feature that's been needed or asked for up to this point.

If there is a real need for it, it wouldn't take much to add support for it. But would need to be done with care as it adds a bunch of new failure modes (timeout, rejected requests etc etc)

---

<div class="post-metadata">

**Author:** ![chris.willing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/chris.willing/32/76579_2.png) [@chris.willing](https://discourse.nodered.org/u/chris.willing)\
**Post date:** [10 October 2021 10:01 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/4 "2021-10-10T10:01:33Z")

</div>

OK thanks, good to know.

---

<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:** [10 October 2021 10:39 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/5 "2021-10-10T10:39:05Z")

</div>

Cant you just get values in `oneditprepare` and store them in a variable that is in scope for both `oneditprepare` and `oneditsave` instead of writing them to the DOM of a hidden element?

---

<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:** [10 October 2021 10:39 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/6 "2021-10-10T10:39:10Z")

</div>

I do this with functions created in oneditprepare rather than save. Such that, if a user changes field1, I add a jQuery on-change function that listens for changes to that field and updates other fields accordingly.

This _does_ let you go off down deep rabbit holes and I use various REST API's in uibuilder in this fashion.

No need to mess with oneditsave since everything is done dynamically.

---

<div class="post-metadata">

**Author:** ![chris.willing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/chris.willing/32/76579_2.png) [@chris.willing](https://discourse.nodered.org/u/chris.willing)\
**Post date:** [10 October 2021 11:49 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/7 "2021-10-10T11:49:35Z")

</div>

Thanks Steve, I wondered about that but I'm still quite new to the Node-RED world and not really sure where to position a holding variable that would be in scope for both of them.

---

<div class="post-metadata">

**Author:** ![chris.willing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/chris.willing/32/76579_2.png) [@chris.willing](https://discourse.nodered.org/u/chris.willing)\
**Post date:** [10 October 2021 11:57 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/8 "2021-10-10T11:57:12Z")

</div>

I did have a quick go at jQuery change function but it didn't immediately work. Now that I have something that does work, I can relax about it and maybe go back to it and work out why it didn't work. The field that changes is a typedInput (selection from a drop down with entries populated dynamically in oneditprepare) - not sure if that is a factor ...

---

<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:** [10 October 2021 11:59 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/9 "2021-10-10T11:59:18Z")

</div>

Yes, that is probably the reason. You will want to use your browser dev tools to work out what is actually changing.

---

<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:** [10 October 2021 12:20 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/10 "2021-10-10T12:20:08Z")

</div>

> [@chris.willing](#):
>
> I did have a quick go at jQuery change function

Did you use the deprecated `.change(..)` function or `.on("change", ... )` ?

The latter should certainly work as per the docs - [TypedInput Widget : Node-RED](https://nodered.org/docs/api/ui/typedInput/#events-change)

---

<div class="post-metadata">

**Author:** ![chris.willing](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/chris.willing/32/76579_2.png) [@chris.willing](https://discourse.nodered.org/u/chris.willing)\
**Post date:** [10 October 2021 13:04 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/11 "2021-10-10T13:04:38Z")

</div>

Yes I used the old .change(..) function. Thanks for the correction - I'll try that.

EDIT: it worked straight away. It's also much nicer to see my Product ID field change as soon as the chosen Device changes.

Thanks again.

---

<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:** [9 December 2021 13:05 UTC](https://discourse.nodered.org/t/using-getjson-in-oneditsave/52051/12 "2021-12-09T13:05:02Z")

</div>

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