Using App Connect with JavaScript Functions

Hi @Teodor,

If the color of the car is later updated from “white” to “red” by my javascript (let’s say, my script polls and pulls this data from an external source), will this dynamically update the value in the related App Connect para tag?

If not, how can this be achieved?

If you update the data, just call the set again like dmx.app.set('car', {type:"Fiat", model:"500", color:"red"});, then it will automaticly update the paragraph and set the text from white to red.

1 Like

Thanks @patrick for the clarification. That’s perfect.

Is it possible to update an existing app-connect variable using the same dmx.app.set function?

If not, is there any other way? I notice the app-connect variable is available under dmx.app.data and has a setter function __setvalue(). When I tried using this setter function to change the variable from “One” to “Two” (screenshot below), it sets the value of the variable to undefined.

Alternatively, is it possible to dom-update the app-connect variable using it’s id, I did create a separate post regarding this as I didn’t want to mix two topics.

Thanks in advance, a clean solution to update app-connect variable from javascript will be a great win for the community.

You can use dmx.parse("var_test1.setValue('Two')") to set the App Connect variable.

1 Like

Thanks a lot @patrick. But, I need to update a variable located within multi-level repeats from my javascript (it’s a price update via socket) - marked-up screenshot at the end of this reply.

The price update is for a particular childId, so I only know the variable’s DOM id, for eg - var_test_102055 (the number part makes it dynamic, I used dmx-bind:id=“var_test_{{childId}}” in code view).

Option-1:
Using your previous suggestion will be too complex, as I need to first figure out the path of this variable within dmx.app.data using the variable’s DOM id (is this possible?), in order to update it like this:

dmx.parse('repeat1.items[7].order_collapse.repeat2.items[4].var_test.setValue("newPrice"')

Option-2
The straight-forward option is to use it’s DOM id and update it similar to text field or paragraph like below, but this doesn’t seem to work for a variable. Please advise what’s the right syntax. At least, I want to know if this is a feasible option at all.

$("#var_test_102055").val("newValue").trigger('change');

The solution you provide will be very helpful for everyone who might deal with javascript interacting with app-connect variables within repeats in the future :slight_smile: Thanks again!

1 Like

You can get the component instance from the DOM element and set the data there directly.

document.getElementById("var_test_102055").dmxComponent.set("value", "newValue");

Your option 2 with setting the value using jQuery and then triggering the change event will work if you use a hidden form input to store the value, it doesn’t work on the variable component.

4 Likes

@patrick
There is a similar thread here:

It is asking about triggering content update after using dmx.app.set to update elments that have a repeat that points to the created variable. Is there a function that can be called (it seems to be invoked when the browser is scrolled) which will update page content?

Hi @patrick, thanks a bunch, just got one last hiccup… Your suggestion works perfectly for simple variable, but mine is an object variable.

My variable var_test_102055, it takes an initial value like this, where orderId and currentPrice comes from a server connect when the page loads:

  `{ "orderId": orderId, 	"currentPrice": currentPrice }`

image

Thereafter, javascript needs to update this variable with the same object whenever there is a price update for this order.

document.getElementById(var_order).dmxComponent.set("value", priceUpdateObj);

The above works only when the variable was not set an initial value, like this:

image

How do I get your suggestion to work when the variable is initialised with an object at the start? Thanks.

Not sure why it wouldn’t work with the initial value. If you want to only update a property of the existing object then try:

// get reference to variable component
var myVariable = document.getElementById(var_order).dmxComponent;
// get order object from component
var order = myVariable.get("value");
// update order
order.currentPrice = newPrice;
// set variable value with updated order object
myVariable.set("value", order);

Thanks @patrick! My object in fact has some 30 properties and I have shown only two in my above reply so that it’s easy for us to troubleshoot.

I just tried making the updates in my dev tool console, and I see that the values are changing, but again reverting back the initial values.

Here is the gif, look closely you will see the row above the console showing the updates in a fraction of second.

When the two parameters are initialised when page load, and then updated:

I was wondering if I need to call some sort of trigger change after changing the values?

When the two parameters are not initialised during page load, they are getting updated just fine…

I might have to update all my 30 properties one by one, this is my fallback option, thanks for the code above. But, would be great if I can pass the full object.

Replace the dmxAppConnect.js file with the one from this zip file.

dmxAppConnect.zip (17.2 KB)

Let me know if that fixes you initial value problem.

4 Likes

@patrick:slight_smile: :slight_smile: :slight_smile: yes it did fix it… Can’t thank you enough!

This thread is GOLD as the various options you provided will help everyone dealing with javascript & app-connect variables in the future… Great learning, thanks again!

6 Likes

I have a bunch of dynamic variables (uses dmx-bind:id="var_test_{{orderId}}").

When this variable’s value is updated (static event), it calls a javascript function that performs some action based on the variable’s value. I have:

<dmx-value id="var_test" dmx-bind:id="var_test_{{orderId}}" onupdated="widget_updater()"></dmx-value>

Now, how do I pass the value of the variable when calling the widget_updater() function? I tried widget_updater({{var_test.value}}), but it threw a js error that it wasn’t expecting curly brackets. @patrick, is this possible?

I would have ideally avoided calling this JS function and try achieve things the wappler way, but my JS function uses d3.js library and deals with data visualisation, so quite advanced, so don’t have any other way. Need to know if this is possible, else I have to re-design to find an alternative way.

You can’t use it like that directly in JavaScript. You can call the App Connect parse function to parse the expression and then use the result like:

widget_updater(dmx.parse("var_test.value"));
2 Likes

Hi @patrick,

Is there anyway I can use dmx.app.name directly through a template expression? If not, how could I store that in a variable and then reuse?

I’ve tried several ways with no luck. Pretty sure it’s quite straightforward.

<div is="dmx-browser" id="browser"> </div>
<dmx-json-datasource id="trans" is="dmx-serverconnect" dmx-bind:url="../../assets/locales/{{browser.language}}/{{dmx.app.name}}.json"></dmx-json-datasource>p
<script>
  dmx.app.set('appName', dmx.app.name);
</script>
<div is="dmx-browser" id="browser"> </div>
<dmx-json-datasource id="trans" is="dmx-serverconnect" dmx-bind:url="../../assets/locales/{{browser.language}}/{{appName}}.json"></dmx-json-datasource>

That was one of the ways I tried :smiley:

I get this error TypeError: dmx.app is undefined

Although If I query it via console just after I can see it’s not undefined.

Is the dmxAppConnect.js included before the script block with the dmx.app code?

I’ve tried at the end of head, at the beginning of body and at the end of body. App Connect is at the beginnning of head. Always the same error.