inicio mail me! sindicaci;ón

Running into OpenLaszlo Limitations

One of the things that got me interested in OpenLaszlo was its pretty cool databinding features, which meant i could take in data from any standard XML document (be it a web page, xmlrpc, or even SOAP) and prototype a little interface around it very quickly, as i previously mentioned in my previous posts.

However, today i decided to take it a step further. I wanted to provide an interface to edit the data i obtain from a request and send back the results to the server. I also wanted to make use of the Ruby on Rails framework’s support for REST.

Being the naive person i am, i thought it was going to be a walk in the park. In OpenLaszlo, all you need to do to grab and display your data from the server is:

  • Make a dataset and point it to your data (e.g. “http://localhost:3000/projects/1.xml”)
  • Make a control with “datapath” set to an appropriate location in your dataset in XPath format (e.g. “dset:/project”)
  • Call “doRequest” on your dataset

The call to “doRequest” can be done like so:


dset.setQueryType('GET');
dset.doRequest();

So naturally, i thought in order to POST the data from the dataset back to the server, i could do:


dset.setQueryType('POST');
dset.doRequest();

Which of course was completely wrong. I assumed that the API would work both ways (i.e. sending the data when the querytype is ‘POST’), which of course it didn’t. The only slightly helpful thing i could do was set the query string. However, this wasn’t quite compatible with REST, so i couldn’t use it as a solution.

After searching about a bit though, i came up with another solution:


var dp = new LzDatapointer();
dp.setPointer(parent.datapath);

var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open('POST', url, true);
xmlHttpRequest.send(dp.serialize());

“Great!” i thought, “This should work!”. Sadly though, it didn’t. It seems that OpenLaszlo’s XMLHttpRequest doesn’t send any data in a POST. Great.

A short while later, i realised i should be using a ‘PUT’ request for updating my REST-ful object. The final nail hit the coffin when i got a nice error message from XHttpRequest – “method ‘PUT’ not supported, use GET or POST”. Aaaagh!!

Safe to say, OpenLaszlo’s data binding API is pretty one-sided when it comes to data. Grabbing data? fine. Sending data? welcome to hell. And not even XMLHttpRequest is of any use, unless you want to send a long long query string, or just stuff everything in the headers, both options which contradict REST.

In the future i think i’m going to take a look at Adobe’s Flex. I suspect it might handle REST requests a bit better.

  • Héryk Julien
    Stuck between a rock and a hard place

    Thanks for the rapid response!!! 
    This is a major drawback in the usability of OpenLaszlo in designing XML driven applications. I spent several weeks learning and designing a Laszlo XML driven FGDC metadata editor... and let’s just say that I’m very disappointed with this outcome! Isn’t Laszlo’s strength supposed to be XML driven applications??!!!! Dop!

    I’ll follow your suggestion and try to implement a solution on the server side (Apache Cocoon http://cocoon.apache.org/) to decode Laszlo's xml Post.

    I posted my question on the Laszlo forum here: http://forum.openlaszlo.org/showthread.php?p=37241#post37241

    I hope this will be fixed in a near future!
    Cheers
    Héryk
  • Héryk,

    I've not played about with OpenLaszlo for months, but i'll see what i can recall.

    If you take a look at one of my other posts, specifically http://www.cuppadev.co.uk/2007/08/08/openlaszlo-version-of-the-previous-flex-example/ , then i eventually figured out that the "lzpostbody" parameter was the key.

    The code i ended up with is http://www.cuppadev.co.uk/assets/2007/8/8/manage_test.txt .

    Keep in mine though that if you are running your app in SOLO mode, then in all likelihood your POST data will automagically be escaped. My solution to that snag here -> http://www.cuppadev.co.uk/2007/08/09/openlaszlo-xml-workaround/ .

    Good luck. :)
  • Héryk Julien
    Hi James,
    I tried the setQueryParam() in LZ 3.3.3 and 4.0.10 to post data and it doesn't work ! I also tried the setPostBody() in LZ 4.0.10 and it also failed! You seem to have made it work... could you post an example?

    FYI, here is my dataset…

    <dataset name="dsSendData" src="$once{'http://localhost:8080/cocoon/devHeryk/metadata/sendMeta/' + LzBrowser.getInitArg('getMeta') + '.xml'}" request="false" type="http"/>

    and my 2 attempts with setQueryParam()…

    <method name="sendData" args="action">
    var dp =canvas.datasets.meta.getPointer();
    var d =canvas.datasets.dsSendData;
    dp.selectChild();
    var sRequest = dp.serialize();
    d.setQueryParam("lzpostbody",sRequest);
    d.setQueryType("POST");
    d.doRequest();
    </method>


    and setPostBody()…

    <method name="sendData" args="action">
    var dp =canvas.datasets.meta.getPointer();
    var d =canvas.datasets.dsSendData;
    dp.selectChild();
    var sRequest = dp.serialize();
    d.setPostBody(sRequest);
    d.setQueryType("POST");
    d.doRequest();
    </method>


    Thanks
    Héryk
  • Henry Minsky
    There is a single magic query arg named "lzpostbody", which if you set it, will be sent as the literal POST body, without form-encoding or anything.

    In an upcoming release, this will be accessed via a new API on dataset called setPostBody().
  • Here's an example code on how to post an XML dataset as a String to a server. Hope that helps...





    a
    b
    cc








    var xmlString = canvas.datasets['theData'].serialize();
    datasetForSending.setQueryParam("xml", xmlString);
    datasetForSending.setQueryType("POST");
    datasetForSending.doRequest();
  • Henry,

    Thanks very much for the suggestion. It seems to work rather nicely. :)

    Regards,

    James
blog comments powered by Disqus