Using App Connect with JavaScript Functions

In some cases it's required to read a JavaScript variable or object values and use them in App Connect. In other cases it's required to use a dynamic App Connect expression in your own custom JavaScript functions. Although we don't provide a visual interface for these operations, both are possible with App Connect.

We will show you a couple of simple examples, which show you how to do this but it applies for any complex function you might be using.


Using App Connect Expressions in JavaScript Functions

You can use dmx.parse to parse expressions inside JavaScript. We have the following JavaScript function:

<script>
function myFunction() {
    var myVar = 'abc';
    console.log(myVar);
}
</script>

But we want to use an App Connect expression for the variable myVar, let’s say an App Connect variable value, which changes dynamically:

<dmx-value id="var1"></dmx-value>

All we need to do is to add dmx.parse('dynamic_expression') as a value for our JavaScript variable:

<script>
function myFunction() {
    var myVar = dmx.parse('var1.value');
    console.log(myVar);
}
</script>

NOTE: This can be any dynamic expression, not only an App Connect variable.

So the results can be seen when we run the function:

Screenshot_5

Accessing JavaScript Variables Values with App Connect

You can use dmx.app.set('varName', varName) to access JavaScript Variables Values with App Connect. We have the following JavaScript function, which contains an object:

<script>
    function myFunction() {
        var car = {type:"Fiat", model:"500", color:"white"};
     }		
</script>

NOTE: it can be a simple variable as well.

We want to use the object values within App Connect. In our example, we will use the values with an Inner Text dynamic attribute on the page:

 <p dmx-text=""></p>

In order to make the object properties/values available for App Connect, we add dmx.app.set to the function:

<script>
    function myFunction() {
        var car = {type:"Fiat", model:"500", color:"white"};
        dmx.app.set('car', car);
     }		
</script>

The first value (in single quotes) is how you want to name the object (or variable) in App Connect, the second value is the object (or variable) name from your JavaScript function. It’s a good practice to keep them the same.

Then on our page we add:

 <p dmx-text="car.color"></p>

And when we run the function, the car color will be displayed on the page:

Screenshot_6


These are the basics of using JavaScript with App Connect, you can extend them according to your needs.

15 Likes

Absolutely brilliant, this could not have been explained to me at a better time, thanks Teo.

2 Likes

Agreed! Thanks very much @teodor!

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!

5 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