Feb 14

As you likely know, OpenLaszlo’s scripting language is based on Javascript - aka ECMAScript 3. Now, Javascript is a weakly dynamically typed language (debatable) and has a habit of generating surprising results. Regardless of whether these ‘gotchas’ are a result of the weak dynamic typing or simply Javascript being Javascript, the consequence is that OpenLaszlo scripting is often a bit quirky.

One quirk I just hit had to do with an animator producing funky results when used in conjunction with a data set. I was simply using the data set to initialize a view to a specified width. The problem was that when I specified the width directly (e.g. ‘150′), things worked as expected. However, when I substituted in the data path reference, all I got was junk. See for yourself:

Hard Coded

width changed to
150.150996008178
width changed to
150.691763283001
width changed to
151.617937604377
width changed to
154.079897270667
width changed to
161.488770028828
width changed to
179.951211667618
width changed to
207.510261932941
width changed to
235.523454865409
width changed to
275.229479425737
width changed to
290.190074409226
width changed to
295.099595336075
width changed to
298.583023698865
width changed to
299.67686271424
width changed to
300

Data Set

width changed to
1500.274198962414936
width changed to
1500.2741989624149362.41547011242939
width changed to
1500.2741989624149362.415470112429394.77836342318196
width changed to
1500.2741989624149362.415470112429394.7783634231819614.2608297578881
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.7813996770265
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.781399677026545.4549816439118
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.781399677026545.454981643911826.9345067269413
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.781399677026545.454981643911826.934506726941313.4332687238966
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.781399677026545.454981643911826.934506726941313.43326872389665.31212008192
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.781399677026545.454981643911826.934506726941313.43326872389665.312120081921.19871422190803
width changed to
1500.2741989624149362.415470112429394.7783634231819614.260829757888135.781399677026545.454981643911826.934506726941313.43326872389665.312120081921.198714221908030.156146668481369
width changed to
150150

It seemed odd that in the case of the data set usage, the animator continued to append new values onto the end of the string. Furthermore, these values seemed to be generally in-line with what the animator should be doing - animating the width up to twice its original value. Then it hit me - Javascript thought that the value in my width attribute was a string, and it did its best to ‘animate’ this string. The value ‘150′ was converted to an number automatically by the animator to perform the animation, and at each iterative step in the animation, the current delta was added on to the original value. However, although the delta was a number, the original value was a string. So, OpenLaszlo ended up concatenating the delta value on to the end of the existing original value, resulting in one nasty looking kindof correctish looking string. Now, that’s obviously not going to work, is it?

The Solution

Make sure you always convert (and validate) data from a data set before you use it. In my case, all I had to do was to add a call to Number() around my datapath.xPathQuery():

No Bueno

<handler name="ondata">
 awesomeView.setWidth(datapath.xpathQuery("@awesome_width"));
 coolView.setWidth(datapath.xpathQuery("@cool_width"));
</handler>

Mucho Mejor

<handler name="ondata">
 awesomeView.setWidth(Number(datapath.xpathQuery("@awesome_width")));
 coolView.setWidth(Number(datapath.xpathQuery("@cool_width")));
</handler>
Feb 13

While slaving away on a recent data-intensive Laszlo project, I happened across the following error:

INFO: __LZgetNodes: p is null in Datapath for container  name: c  id: c

Great - another cryptic error message. I’ll spare you the link by link Googlechase and code archealogy that ensued and do what you wish your linear algebra tutor would do: just tell you the right answer.
It turns out that the problem was in the following event handler:

<handler name="ondata">
 util.setAttributeIfDefined(this, "height", Number(datapath.xpathQuery("project/@video_height"))); 
 util.setAttributeIfDefined(this, "width", Number(datapath.xpathQuery("project/@video_width"))); 
</handler>

As I discovered, I was attempting to access a datapath that had yet to be linked to a data set. Note to Laszlo Systems: Could we get a bit of contextual help here? Like we’re spoiled with when we access a non-existent attribute? You know, like so:

hello.lzx:2:20: attribute "size" not allowed at this point; ignored 
hello.lzx:2:20: found an unknown attribute named "size" on element "text", however there is an attribute named "fontsize" on class "text", did you mean to use that?

The Solution

Make sure you’ve actually got a data set associated with the datapath before you use the datapath. The easiest way to do this is to use an ondata event handler instead of oninit, onload, or any of their non-data aware brethren.