If you need to return the result of a function assign it to a variable:
ret = function() {
let c = 1
return a+b+c
}()
If you need to return the result of a function assign it to a variable:
ret = function() {
let c = 1
return a+b+c
}()
const vm = require('vm')
exports.run = async function (options) {
const code = "ret = function() { " + options.code + " }()";
...
}
Maybe one more option to select user preference? āRun within functionā
WOW! this is awesomeā¦ thanks for doing this JonL
Sticking to the standard means less maintenance and problems if node guys decide to introduce changes to vm.
Additionally I need to understand better how promise handling works in VM context so I have to test that before prepending a variable to a function.
Is it unbearable for your eyes having to add a variable and assign it to the function result? I understand itās kind of unsettling not being able to use return in the main code. I believe this is by design to secure the sandbox.
I am more concerned about the lack of a proper control in the UI that handles code although this is expected as nobody has asked for itā¦until now
@george do you guys have by any chance an undocumented control for code with linting and beautifier?
Not a problem!
Thereās a bug with the Output checkbox: it comes ticked by default, but it doesnāt really output anything. If I untick and tick it again it works
Edit: As a new feature, is it possible to define the schema of the output? Like what happens with API Action or Set Value (this last oneās broken due to a bug)
Regarding the output toggling this should be āfixedā with the last version 1.1.0
I changed it to default to false.
Related to:
For custom extensions the output schema is defined in a json file and itās static but itās true that it is available for the API action. @george is this undocumented or not available for custom modules?
return 'hello world'
console.log()
and the output will be forwarded to the server console.@JonL Iām struggling with getting it to work, Iām not sure if I am using the extension wrongly or if my code is wrong.
I do think this is the exact use case for your extension though, need to apply a little bit of JS to manipulate dataā¦
"query_products": [
{
"id": 13,
"ac_tags": "tag1, tag2"
},
{
"id": 14,
"ac_tags": "tag3"
}
],
I want to loop over the data and for each product: split the ac_tags
and then push the values into one array. Expected outcome:
acTagsArr = ["tag1, tag2, tag3"];
Iām trying to get this done with the following JS:
acTags = []; //declare my output var
tagsSplit = tags.split(','); //Split the 'ac_tags' so I get an array where 1 tag = 1 item
acTags.push(...tagsSplit); //push the split items into the output var
Iām expecting an output of: acTagsArr = ["tag1", "tag2", "tag3"]
(still need to remove the comma and make it a single string.)
These are the settings of the plugin
This is the location (in a repeat)
This is my current output:
"repeat_push_to_array": [
{
},
{
}
]
What version of RunJS are you running?
This code should work with the latest 1.2.0:
return tags.split(",")
Also note you have a space after each comma (double-check if this is the case), so this is the code:
return tags.split(", ")
For previous versions of RunJS, omit the return keyword:
tags.split(",");
The method .split() already returns an Array, so you can return it directly without creating acTags2
Edit: Actually, your problem is youāre not actually returning acTags
acTags = []; //declare my output var
tagsSplit = tags.split(','); //Split the 'ac_tags' so I get an array where 1 tag = 1 item
acTags.push(...tagsSplit); //push the split items into the output var
return acTags; // RunJS 1.2.0
acTags; // Previous RunJS versions
Thanks @Apple appreciate the help!
I got a bit further, I didnāt realise we need to use return
now.
With this code:
return tags.split(",").map(item => item.trim());
I get:
"repeatACtags": [
{
"ac_tags": [
"tag1"
]
},
{
"ac_tags": [
"tag2",
"tag3"
]
}
]
so now I want to make it one array, which Iāve done before in a similar way:
This is outputting nothing. Iām guessing because Iām not passing the acTagsArr
to the RunJS. But if I do that I think my variable will stay within this scope of this RunJS.
Any idea?
Your array declaration (#1) doesnāt matter to RunJS (even if you pass it in Data), the scope is isolated as you guessed (pass by value, not by reference)
Similarly, the step #3 to #1 doesnāt happen - the value returned by RunJS is not magically filled into acTagsArr (RunJS has no reference to it). You need to put a Set Value acTagsArr after the RunJS step, and you select in the Data Binding Picker the value RunJS returns
Okay I think you mean similar to this?
Current set up:
Output:
The acTagsArr
that I set with āSetValueā is getting the values pushed as expected.
"acTagsArr": [
"tag1",
"tag2",
"tag3"
]
Then I just need the last step: .join(',')
So I put it in the repeat now, because it should join the array after the last repeat.
Outcome:
"repeatACtags": [
{
"ac_tags": [
"BOUGHT | NTSL Ebook"
],
"pushToArray": 1,
"joinArray": "tag1"
},
{
"ac_tags": [
"these are tags",
"here"
],
"pushToArray": 3,
"joinArray": "tag1,tag2,tag3"
}
]
But then Iām not sure how I can get that final joined array.
Trying like this:
But this is not giving me any output.
EDIT: Which makes sense to me now because itās an array, so I need to select the last item somehow. Iāll try this out now
Please note the variable scope, thereās no guarantee youāll be able to access the variable joinArray outside the Repeat step. You need to define a global name for that (name ājoinArrayā, global name ājoinArrayGlobalā
And then on finalArray you get {{joinArrayGlobal}} - you wonāt see this in the Data Binding Picker
Happy to help
Oh wow that works perfectly. First time Iām using the Global Name propertyā¦
Thanks @Apple I appreciate it a lot!!
Iām still wondering if I can replace my custom formatter with this extension?
Iām using a pushSpread
formatter which is just:
exports.pushSpread = function (arr, obj) {
return arr.push(...obj);
}
return acTagsArr.push(...ac_tags)
One liner:
return [tags.map((e) => e.ac_tags).join(', ')]
Should return a single array of tags comma separated.
But acTagsArr
is defined as a āset valueā . So with the custom formatter I can push things into this array. But with the runjs Iām not sure how to push into this array
Today I learned
But with the runjs Iām not sure how to push into this array
Yeahā¦ Probably would have to convert acTagsArr to a global variable, and then Set Value on it with the output of RunJS.
Here comes the king of one-liners, Mr. Jon Liner
I love one liners. Itās like completing the newspaper puzzle itās a hobby
Hmm nice ideaā¦ Need to move on now though so wonāt try it, but thanks for all the input. Learning a lot
@JonL Very curious how youād approach thisā¦ Your one liner looks good but leaves me with 2 issues still:
the join
is not foolproof. Right now the tags can be separated with or without trailing spaces depending on user input. (Iāll sanitize that input better in the future but Iād like server side code that can handle exceptions)
The global variable issue. See my earlier post: š RunJS 1.2.0
Any alternative idea on how to iterate over each object, grab the values of a certain key and add them to a global array?