Creating a SSJS variable from a REST resource asset


(Tom Stringer) #1

I can’t figure this problem out, but it feels like there must be an answer…

I have a paint layout from which I’m calling a REST Resouce asset using server-side javascript.

I want to assign the output of the REST Resource asset (a JSON array) to a variable in the SSJS of the paint layout, but I can’t seem to make it work. I can print the result to the frontend, but I can’t get that same result assigned to a variable within the SSJS script.

Is it possible to do this? Or am I just going to have to find another way?


(John gill) #2

How are you including the REST Resource? You won’t be able to use %globals_asset_contents:1234% because that’s not evaluated until after SSJS (usually).

For this kind of thing I’d use:

var q = %nested_get_blerp^with_get:blerp=1234^as_asset:asset_contents_raw%;

Equivalent to %globals except it’s evaluated before the SSJS is run so you can assign it to a variable. blerp can be anything, it’s just using a made up GET variable as a way of running the asset_contents_raw modifier on a hardcoded asset id.


(Bart Banda) #3

Global keywords are run first, then SSJS (https://matrix.squiz.net/manuals/concepts/chapters/server-side-javascript#processing-order), so this should work. But yea, depends on the whole setup.

If you are just injecting the REST asset contents as a global keyword into your SSJS code, it should work. Can you share a bit more info about the whole implementation?


(Tom Stringer) #4

Thanks @JohnGill and @Bart

I’m using globals keywords with the method described here: Problems with keyword replacement values as modifiers

I have a REST Resource asset (#12345) setup as follows:

URL: https://%globals_get_parameters%/v2/posts.json
<script>
	var response = JSON.parse(_REST.response.body),
	    limit = %globals_get_numberToReturn%;

	var newArray = [];
	for (i = 0; i < limit; i++) {
	    var newStructure = {
	        "local_asset": false,
	        "platform": "Blogs",
	        "use_target_blank": true,
	        "type": "news",
	        "id": response[i].id
	    };
	    newArray.push(newStructure);
	}

	print(newArray);
</script>

It returns:

[
	{
	  "local_asset": false,
	  "platform": "Blogs",
	  "use_target_blank": true,
	  "type": "news",
	  "id": 623
	},
	{
	  "local_asset": false,
	  "platform": "Blogs",
	  "use_target_blank": true,
	  "type": "news",
	  "id": 599
	},
	{
	  "local_asset": false,
	  "platform": "Blogs",
	  "use_target_blank": true,
	  "type": "news",
	  "id": 588
	}
]

In the paint layout, I declare some variables that are passed to the REST Resource asset and then attempt to assign the output to a variable.

<script>
  var parameters = '%asset_metadata_test%',
  		numberToReturn = 3;

  // This is the REST Resource asset that calls an API endpoint based on the parameters passed to it with the GET variable and returns a JSON array of objects (as above). Works fine printing to the frontend.
  print('%' + 'globals_asset_contents:12345^with_get:params=' + parameters + '^with_get:numberToReturn=' + numberToReturn + '%');

  // I want to assign the output from the above print statement to a variable


  // EXAMPLE 1 - try to assign to the variable using the print statement
  // example1 just prints the objects directly to the frontend: '[object Object],[object Object]' etc. 
  var example1 = print('%' + 'globals_asset_contents:12345^with_get:params=' + parameters + '^with_get:numberToReturn=' + numberToReturn + '%');
  // example1 is a 'number' 
  print(typeof example1);

  // EXAMPLE 2 - try to assign to the variable without the print statement
  var example2 = '%' + 'globals_asset_contents:12345^with_get:params=' + parameters + '^with_get:numberToReturn=' + numberToReturn + '%';
  // is a 'string'
  print(typeof example2);
  print(example2[0]); // returns '%'
</script>

I had a quick look at the method suggested by @JohnGill but I suspect that doesn’t allow me to pass the additional GET parameters through that I need.


(Bart Banda) #5

Yea so this won’t work, as you are effectively running SSJS before the global keywords are evaluated, so by the time the JS runs, those global keywords where you want the arrays to appear from your REST asset haven’t been replaced yet.

The way to do this is just to run all of your JS inside the REST asset, you could even include the JS from a JS file or a standard page if you want to keep it neater as well. Is there a reason why you need to separate the JS out like this or can you combine it?


(Tom Stringer) #6

Nuts. I suspected that might be the case, thanks Bart.

We’re trying to do a fairly hair-raising set up lookups of multiple external and internal recources and then process the various results into a single array via a Content Container Template. It’s pretty tangled. I’ll have a think about some of the other suggestions you’ve mentioned.


(Bart Banda) #7

No worries. If you are keen, maybe we could set up a call to talk through the problem in more detail, could even have a look at your system to see what your asset setup is that you’re dealing with. Shoot me an email if you’re keen to bounce some ideas around.