Skip to main content
Participant
January 25, 2018
Answered

Passing information from jsx to js.

  • January 25, 2018
  • 4 replies
  • 8700 views

Hello Community,

I have a problem with passing information from jsx to js file.

my jsx file:

$.extendScript = {

  test : function() {

    return "string";

  },

}

my js file.

(function () {

    var cs = new CSInterface();

    var variable = "";

    cs.evalScript('$.extendScript.test()', function(result) {

       variable = result;

       alert("variable in evalScript =" + variable);

    });

    alert("variable in outside = " + variable);   

}());

In evalScript function the variable get's the string from jsx function but when I want to use it outside I get empty string again.

Also I get the alert outside evalScript first in order. Why this happens?

Does anyone know why this happens and how to fix this?

Best Regards

This topic has been closed for replies.
Correct answer Bruce Bullis

I don't know about 'Why', but...

See PProPanel for a working implementation.

JavaScript: Samples/ext.js at master · Adobe-CEP/Samples · GitHub

https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/ext.js#L66

ExtendScript:  Samples/Premiere.jsx at master · Adobe-CEP/Samples · GitHub

4 replies

pctechtv
Inspiring
August 5, 2019

Most of this topic went over my head. Is there a way to get information from the jsx file back to the js script in your html file? I am trying to use a folder picker in the form of:

var fPath = decodeURIComponent(Folder.selectDialog("Choose the output directory"));

I can get the path and alert from the jsx file but I cannot seem to set it to a variable to display to the user in a panel field. Is this possible? Thanks

Bruce Bullis
Community Manager
Community Manager
August 5, 2019

Is there a way to get information from the jsx file back to the js script in your html file?

Yes; see PProPanel's usage of getUserName.

pctechtv
Inspiring
August 5, 2019

Hi, thanks so much for the reply. I am still having no luck with what I am trying to accomplish. So that function is similar to the one I have created. Using the one you show as an example, how would I get the userName (returned) variable to be persistent so that I could update a field in my panel with its value? Thanks

sberic
Legend
January 28, 2018

klemenm  wrote

In evalScript function the variable get's the string from jsx function but when I want to use it outside I get empty string again.

Also I get the alert outside evalScript first in order. Why this happens?

Does anyone know why this happens and how to fix this?

As others have pointed out, CSInterface.evalScript is an asynchronous* function.

* There is currently a bug on Adobe apps in macOS that causes evalScript to run synchronously. This doesn't help you, however, because the callback still gets scheduled to occur after the current context completes.

Here's how your code is evaluated:

  1. Call to evalScript sends a request to process the code you send it.
  2. Your "outside" alert is triggered. The captured variable variable is still the empty string.
  3. The Panel (JS) processing (started via some callback, e.g. button click callback) completes.
  4. The ExtendScript (JSX) context is started and begins to process the request you sent it.
  5. The script you passed to ExtendScript (JSX) is processed, generating the return value you are interested in (coerces it to a string).
  6. The ExtendScript (JSX) context sends a request to process the string to the JS using the callback you specified.
  7. The panel (JS) context runs the callback that you provided to evalScript and only now will it have the chance to set the captured variable variable to the string that your JSX code produced. Your "inside" alert is triggered.

What you really want to do is run your "outside" alert after the "inside" code has had a chance to run. To do this you need to somehow get #2 to occur after #7. This is where the setTimeout function comes in handy. Try this:

(function () { 

    var cs = new CSInterface(); 

    var variable = ""; 

    cs.evalScript('"string"', function(result) { 

       variable = result; 

       alert("variable in evalScript =" + variable);  

    }); 

    setTimeout(() => {alert("variable in outside = " + variable);}, 0);

}());

Note that I got rid of the special JSX-side function that simply returns "string". Rather, I just made the evalScript simply return that directly.

The important part is line 8. That schedules the anonymous, inline function to be called at a later date (the 0 at the end means "as soon as possible" - if you had heavy script in your JSX [on applications running in Windows] then you might need to delay even further with larger numbers). Honestly, though, the correct thing to do is simply trigger another function call that makes use of that captured variable from within the function itself. Both the callback passed to evalScript and the one passed to setTimeout capture a reference to the same variable instance which means that when one changes, both do. It's merely a matter of determining which callback is triggered earlier.

I hope this helps!

Premiopolis
Inspiring
January 27, 2018

cs.evalScript() is an asyncronous call, meaning it will wait until it receives a reply from your jsx script before setting ‘result’ and executing the callback function your evalScript.

While asyncronous functions wait patiently before executing their callbacks, that ‘waiting’ does not halt execution of the next line of code, which in your case is the ‘outside’ alert.

So your code will execute your second ‘outside’ alert first and your first ‘in evalscript’ second.

More on asyncronous coding here Introduction to asynchronous JavaScript (Example) | hack.guides()

Bruce Bullis
Community Manager
Bruce BullisCommunity ManagerCorrect answer
Community Manager
January 26, 2018
Inspiring
November 14, 2018

bbb_999Could You please tell me how I can create callback on this event?

csInterface.evalScript('$._PPP_.registerProjectPanelSelectionChangedFxn()'); // Project panel selection changed

I want that the trackitem of currently selected clip will be in the input box of my Panel.

My goal is to create button on panel that if I push it, will change scale of currently selected clip.

Therefore I decide to take trackitem path from input box and send it to jsx.

May be it can be done with another algorythm?

Premiopolis
Inspiring
November 14, 2018

n.abola  wrote

bbb_999Could You please tell me how I can create callback on this event?

csInterface.evalScript('$._PPP_.registerProjectPanelSelectionChangedFxn()'); // Project panel selection changed

I want that the trackitem of currently selected clip will be in the input box of my Panel.

My goal is to create button on panel that if I push it, will change scale of currently selected clip.

Therefore I decide to take trackitem path from input box and send it to jsx.

May be it can be done with another algorythm?

csInterface.evalScript('$._PPP_.registerProjectPanelSelectionChangedFxn()', function( ResultsFromJsxContext ){

  //Command block here

});