• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Parse JSON data in jsx from js

Contributor ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

Curently I pass data from my js to jsx like so:

This is in my js file.

      const orderData = JSON.parse(orders);
      const exc = `setupPlateTemplate('${orders}')`;
      csiRun.evalScript(exc);

I can confirm the data goes to jsx  and that setupPlateTemplate method fires.

my jsx file:  

#include '../js/json2.js'

function setupPlateTemplate(orderData) {
  
  var oData = JSON.parse(orderData);
  alert(oData);

    }

 

this does not work.  

My file structure is: 

cep_directory:

jsx -> product.jsx

js -> json2.js

for this reason file path to the json2.js is.  

'../js/json2.js'

 

Any idea what I'm doing wrong?

TOPICS
Scripting

Views

2.9K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Enthusiast , Dec 30, 2019 Dec 30, 2019

The $.evalFile method is what can load scripts from within other scripts. In this response, I'm just showing you how to wrap it within evalScript, this const is the same as CSInterface.evalScript since CSInterface is basically an alias object. You'd likely need something like this:

 

 

let root = decodeURI(
  CSInterface.getSystemPath("extension")
).replace(/file\:\/{1,}/, "");

CSInterface.evalScript(`$.evalFile('${root}/js/json2.jsx')`);
CSInterface.evalScript(`$.evalFile('${root}/jsx/product.jsx
...

Votes

Translate

Translate
Adobe
Enthusiast ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

Hi, I'm not too much a fan of the include syntax -- I think it's generally only needed when you're confined to .jsx files only. Maybe you can't include .js files from a .jsx? For my own setup, I have folders which my panels will comb through and evaluate all files within prior to evaluating my main scripts. The below is also included in that cluecumber library I'd linked earlier.

 

This is likely much more complex than what you're asking or expecting, but my data flow is something like this:

  1. The panel begins to mount
  2. The panel evaluates and runs any universal script files (support for JSON, console.log, and ES6 array methods like filter, map and forEach inside jsx files)
  3. The panel evaluates and runs the main script file, but there is little to no auto-executing code within it. Everything exists within functions which can easily be called via evalScript from user interaction on the panel later.
  4. The panel finishes mounting and renders HTML

 

The general method is like this, bearing in mind that it looks complex because I'm not using CSInterface and am sidestepping it so there's no conflict with your own CSInterface variable name or scope:

 

 

 

 // Correctly loads and evaluates a script regardless of whether Animate or regular CEP app  
  function loadScript(relpath) {
    // relpath is assumed to be relative to your directory, as in './jsx/json2.jsx'
    //
    // Find the absolute location of your current CEP extension
    let root = decodeURI(
      window.__adobe_cep__.getSystemPath("extension")
    ).replace(/file\:\/{1,}/, "");
    //
    // Remove the relative prefix and concatenate relative and absolute positions
    let fullpath = `${root}${relpath.replace(/^\./, "")}`;
    // 
    // Use the proper evaluation method regardless of current host app
    window.__adobe_cep__.evalScript(
      !/FLPR/.test(
        JSON.parse(window.__adobe_cep__.getHostEnvironment()).appName
      )
        ? `$.evalFile('${fullpath}')`
        : `fl.runScript(FLfile.platformPathToURI("${fullpath}"))`
    );
  }

 

 

 

In reality it can be much more simple, but you'd still need to use the root path variable from above or use my own library CEP-Spy to so the logic is done for you

 

 

 

const evalScript = window.__adobe_cep__.evalScript;

// json2.js might as well be .jsx, not sure if you can include .js files directly
evalScript(`$.evalFile('${root}/js/json2.jsx')`);
evalScript(`$.evalFile('${root}/jsx/product.jsx')`);
evalScript(`setupPlateTemplate('${JSON.stringify(someData)}')`);

 

 

To clarify, this allows you to run any number of scripts from your panel, which intersect and share the same memory/scope. With this method, you do not need the <script>./jsx/product.jsx</script> line of your manifest.xml at all

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

Thanks for the response, how would I achieve it using? CEP-Spy?

Would it be using this code block:  

const evalScript = window.__adobe_cep__.evalScript;

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

The $.evalFile method is what can load scripts from within other scripts. In this response, I'm just showing you how to wrap it within evalScript, this const is the same as CSInterface.evalScript since CSInterface is basically an alias object. You'd likely need something like this:

 

 

let root = decodeURI(
  CSInterface.getSystemPath("extension")
).replace(/file\:\/{1,}/, "");

CSInterface.evalScript(`$.evalFile('${root}/js/json2.jsx')`);
CSInterface.evalScript(`$.evalFile('${root}/jsx/product.jsx')`);
CSInterface.evalScript(`setupPlateTemplate('${JSON.stringify(someData)}')`);

 

 

 

In the above code, the files are loaded/evaluated synchronously. JSON support is added first, then your main script is eval'd, then you're free to call a function in your main script which requires JSON.

 

I only mention CEP Spy because it abstracts a lot of the panel identity for you, so the above could instead not need CSInterface at all:

 

 

 

let root = require('CEP-Spy').default.path.root;
// or
// import spy from 'CEP-Spy'

window.__adobe_cep__.evalScript(`$.evalFile('${root}/js/json2.jsx')`);
window.__adobe_cep__.evalScript(`$.evalFile('${root}/jsx/product.jsx')`);
window.__adobe_cep__.evalScript(`setupPlateTemplate('${JSON.stringify(someData)}')`);

 

 

 

The reason I avoid using it is because I don't know which CSInterface file version you use, or name and naming convention, or your method of loading CSInterface and instantiating it, etc. So CEP-Spy works regardless of how you personally do things, and doesn't even need you to have CSInterface.js inside your panel.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

LATEST

Btw, if you're still only using an Array and if it's simple enough, there's no need for JSON. You could just do something like:

 

window.__adobe_cep__.evalScript(`setupPlateTemplate('${someArray.join(",")}')`);

 

And then inside of JSX:

 

function setupPlateTemplate(orderData) {
  var oData = orderData.split(",");
  alert(oData);
}

 

As a general rule of thumb a lot of times these things easily become X/Y problems, where you ask how to do X without describing the underlying issue of Y. If Issue Y were "I'm trying to send an Array over an evalScript parameter" the above would be far simpler to do, though the original answer I gave will work for any kind of Javascript type or even very complex arrays with no need for a comma delimeter, or arrays of objects/arrays containing complex data, etc. I'm guessing you're still using an Array but don't know what the actual entries are, otherwise I would've suggested simpler methods first.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines