Passing a JSON or XML object from JSFL to an AS3 panel...
  • Hi, 

    i've build a custom panel using the xjSFL modules, everything work fine. I'm calling functions from my AS3 panel to the JSFL fine. Today i had to implement a method call from the JSFL to the AS3. After struggling a bit, i made it work with a simple callback, just passing a String to my as3 function. But now i need to pass a real object, and after trying to encode my object as both a JSON string or an XML, it always crash when the object is received by the AS3, and i got a very "explicit" ;) error popup saying that there's been an error somewhere...

    After doing many tests, i can tell that the problem is coming from the nested quotes in the JSON (or XML) object, here is the JSON string i'm trying to pass to the AS code:

    '{"nbBalls":10,"nbGems":2}'

    If i pass '{this_is_some_random_text}' , no problem...

    I've seen a lot of post where people are saying that you just need to use JSON or XML to pass object from JSFL to AS3, so i must be missing something quite obvious here...

     

    Thanks!

  • ravennousravennous May 2013

    Hi,

    I had this exact problem and it turn out that the problem is the double quote character.  If you try this '{"this_is_some_random_text"}', note the double quotes, this will break it as well.  

    Sadly I didn't find a fix I just moved on from this problem, because I relalized I didn't need a callback.

    -Raven

  • Hi Raven,

    yes i did this exact same test, that's how i figured out that the problem was coming from the double quotes... That's really weird, a lot of posts on Stack overflow about passing data from JSFL to AS recommend to use XML or JSON to encode/decode the data. As i just have a few parameters to pass i could simply add them to the signature of the callback but i'm working on the level editor of a big game and will need this kind of stuff sooner or later... :/

  • DaveDave May 2013

    Can you post the calling and recieving code, or at least a simplified test version?

    xJSFL has a bunch of built-in code to prevent this situation from arising, I'm just wondering if you're using this or not. If you pass data from JSFL to AS3, this should be handled by JSFLInterface (I'll test when home if there's an issue passing double quotes).

    If you're just passing values from JSFL to AS3 via Module.call() are you saying that doesn't work?

    I can check again when I get home if this is an issue

    Cheers,

    Dave

  • Hi Dave, thanks for your answer, here's the code:

    In my module JSFL file i have this method:

    onLayerChanged:function(event) {
        var myObj = {};
        myObj.color = "red";
        var myObj_json = JSON.encode(myObj);
        trace("myObj_json : " + myObj_json);
        this.panel.call('jsflCallback', myObj_json);
    }

    On the flash side i have my call back, with i registered using 

    ExternalInterface.addCallback("jsflCallback", jsflCallback);

    and here's the callback function:

    public function jsflCallback(obj_json:String):void
    {
        JSFL.trace("Received json object: " + obj_json);
    }

    Here is what i see in the trace: 

    myObj_json : {"color":"red"}

    and i got this error popup:

    JSFL error popup

     

    I've also tried with this:

    onLayerChanged:function(event) {
        var myObj = {};
        myObj.color = "red";
        var myObj_xml = JSFLInterface.serialize(myObj);
        trace("myObj_xml : " + myObj_xml);
        this.panel.call('jsflCallback', myObj_xml);
    }

    The output seems ok: 

    myObj_xml : <object><property id="color"><string>red</string></property></object>

    But then the same error, but in this case i'm not sure what type i should declare for the parameter in my AS callback function.

    Also, from reading the xJSFL doc i think i should be calling my AS function using directly:

    this.call('jsflCallback', myObj_xml);

    But this doesn't work, i've check the panel name declared in the manifest file for the module, it's ok, which i can tell cause the reference to the panel is set properly.

    Thanks a lot.

    -lucas

  • DaveDave May 2013

    That is a bit odd. I'll look into this in the next day or so and get back to you with a fix.

    FWIW, because Flash's JSFL events are screwed in CS6 (I got Adobe to fix them for CC!) I use a polling technique from AS3 to JSFL to pick up changes in the Flash UI.

    For CC I will probably write a proper class that picks up all changes in the UI using JSFL events and forwards them to an listening panels. Another item for the to-do list!

  • DaveDave May 2013

    FWIW, you could also call the panel code using vanilla JSFL, from Komodo with the xJSFL extension, or even just running a vanilla JSFL file (though developing using Komodo is sooo much easier).

    Run the following code to see what results you get:

    function call(panelName, callbackName, value)
    {
    if(fl.swfPanels.length > 0)
    {
    for(i = 0; i < fl.swfPanels.length; i++)
    {
    panel = fl.swfPanels[i];
    if(panel.name === panelName)
    {
    return panel.call(callbackName, value);
    }
    }
    }
    }

    trace(call('PropertiesPanel', 'jsflCallback', {"color":"red"}));

    Let me know how it goes.

    Cheers,

    Dave

  • Hi Dave,

    yes i know for the JSFL events, i've read that on the xJsfl documentation. I'm using the layer changed event for now as a quick way to test my callback.

    I've tried running the code as you suggested. I've simply created a JSFL file from the flash IDE and executed it, but i got the same error, if i swap the object for a String, it works perfectly...

    I'm really surprised that no one seems to have encountered this same problem, i should probably consider replacing my JSON stuff by simple calls with few parameters in callback functions for now.

    And yes i've been using Komodo, but with my team we switched to IntelliJ and i don't think i could ever go back to any other IDE for Flash dev. Oh and Intellij also handles my JSFL project perfectly, i have 1 module with the Flash code and one with the JSFL code, in the same project, it's neat :)

    thanks!

  • DaveDave May 2013

    OK, this is the error we get in Flash CC for the object:

    This is the error we get for a Date:

    But converting either of these to Strings is fine.

    The content of the error doesn't make much sense (I can file a bug with Adobe asking them to return something more meaningful) but the context of the error does, as the receiving AS3 function is strongly-typed; passing non-string values (even in AS3) is suppose to throw an error.

    The trick in this case would be:

    • To pass custom XML use toXMLString(), call, then new XML(value) on the AS3 side
    • To pass Objects using JSFLInterface to serialize to an XML String and deserialize on the AS3 side
    • To pass Objects as JSON, stringify the Object, call, then use a JSON library to parse on the AS3 side

    Attempting this with JSON in CC throws an error however - as the resulting string does NOT have nested double-quotes escaped, so we need to escape them like so:

    call('Test', 'externalFunction', JSON.encode({"color":"red"}).replace(/"/g, '\\"'));

    That gives us the following when passed over the wire:

    Obviously, once this is on the AS3 side, we'd need to decode using a JSON library, like AS3CoreLib, then we can access properties as normal. I guess you'd need to experiment with the XML as well to see how much escaping/unescaping you need.

    At some point (maybe even tonight) I'll look at building this into the module framework, probably extending JSFLInterface to handle the conversion on both sides.

    Anyway, hopefully that will give you a way forward in the meantime :)

    Cheers!

    Dave

    PS. Lucas, if you want to drop me a mail with your IntelliJ setup, and perhaps a screenshot or two, I could add that to the xJSFL docs which will give people another option to create great Flash tools. I'd appreciate it! :)

  • Hi Dave, thanks for the answer,

    The small workaround with the replace() call worked perfectly. Weirdly i had nothing to do on the other side appart simply decoding the JSON data :)

    I'll send you a mail soon regarding my IntelliJ setup!

     

     

  • DaveDave June 2013

    Great - glad it worked! Looking forward to the email.

    Cheers,
    Dave

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with OpenID Sign In with Google Sign In with Twitter

Sign In Apply for Membership