Using App Connect with JavaScript Functions

@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.

Waiting for document ready seemed to do the trick. However I don’t know if this is a good approach.

<script src="../../dmxAppConnect/dmxBrowser/dmxBrowser.js" defer=""></script>
<script>
$( document ).ready(function() {    
	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>

Edit: Not too happy about this solution as it’s calling twice the file I want to retrieve. First without the variable being set.

image

Ah yes, the page must be parsed first. Waiting for document ready is good.

Any way you can think of to avoid the duplicate call while waiting? Check my previous edit.

I ended up changing to a vanilla js dom ready function and I no longer have the duplicate request. I got rid of the 404 error.

<script src="../../dmxAppConnect/dmxBrowser/dmxBrowser.js" defer=""></script>

<div is="dmx-browser" id="browser"> </div>

<script>
	var callback = function(){
	dmx.app.set('appName', dmx.app.name);
	};

	if (
		document.readyState === "complete" ||
		(document.readyState !== "loading" && !document.documentElement.doScroll)
	) {
	callback();
	} else {
	document.addEventListener("DOMContentLoaded", callback);
	}
</script>

<dmx-json-datasource id="trans" is="dmx-serverconnect" dmx-bind:url="../../assets/locales/{{browser.language}}/{{appName}}.json"></dmx-json-datasource>

All peachy now.

1 Like

Hi @patrick,

Can you nest dmx.parse inside a dmx.parse? I’m using the zxcvbn library to check the password strength of an input. But I’m not able to nest two of them.

Maybe you can try the new App Connect Flows for that?

And also the new App Connect global data to inject data straight in App connect root.

1 Like