For the whitespace just replace it with nothing.
return [tags.map((e) => e.ac_tags.replace(/\s/g, '')).join(',')]
The global variable I donāt understand really your issue. Just assign the output of your RunJS step to a global variable.
For the whitespace just replace it with nothing.
return [tags.map((e) => e.ac_tags.replace(/\s/g, '')).join(',')]
The global variable I donāt understand really your issue. Just assign the output of your RunJS step to a global variable.
@karh I have reviewed the conversation and I still donāt quite get the issue with the global variable.
You mentioned that your expected outcome was an array with tags in a comma separated format.
acTagsArr = ["tag1, tag2, tag3"]
The previous one liner should provide exactly that and remove any whitespace.
return [tags.map((e) => e.ac_tags.replace(/\s/g, '')).join(',')]
Now I am lost why you need the global variable? Is it for the next steps?
Hi,
This may seem a stupid question but how to I install this custom extension?
Iāve downloaded the v.1.2 zip from github, and placed the 2 files in the extensions folder as per image below:
Is this correct, or do I have to activate it somehow?
Thanks
You need to remove the folder runjs
as both files should live in the modules
folder.
Thatās been covered in the custom extensions docs already
@JonL I appreciate your persistence in trying to help.
Letās try figure this out Great learning opportunityā¦
Iāve moved it to a test server action so itās easier to test. This is my set up now:
This is what I get when I run this server action:
{
"inputdata": [
{
"id": 13,
"ac_tags": "tag1, tag2"
},
{
"id": 14,
"ac_tags": "tag3"
}
],
"repeat": [
{
},
{
}
]
}
So first question: what am I doing wrong with your one liner now?
The problem is the repeat itself You donāt need it.
Just use the RunJS action with the one liner, add the input data as tags variable, and Bobās your uncle.
Damn. Yes this is what I need, and no the global variable is redundant now. I was trying to get that to work because of the scope of the repeat.
Thanks, this is really nice.
I love these kind of one liners and want to learn more. Iāve been looking at the map function the last few weeks but still donāt quite grasp it.
Can you explain your code a little bit?
This is my take so far:
For easy reading Iām putting the object into a javascript variable
let tags = [
{
"id": 13,
"ac_tags": "tag1, tag2"
},
{
"id": 14,
"ac_tags": "tag3"
}
];
return [tags.map((e) => e.ac_tags.replace(/\s/g, '')).join(',')]` //result: "processInputData": ["tag1,tag2,tag3" ]
Taken apart:
Map is creating a new array, populated with the results of the function we call on every element in the array. So that function is:
(e) => e.ac_tags.replace(/\s/g, '')
(e)
= current processed element, so in the first run that would be:{
"id": 13,
"ac_tags": "tag1, tag2"
}
function(e) {
return e.ac_tags.replace(/\s/g, ''); //result: "processInputData": ["tag1, tag2"]
}
Where /\s/g
is RegEx matching white space (\s) and stop after the first match (/g)
So now the beginning white space is replaced with ''
(nothing) if itās found.
let tags = [
{
"id": 13,
"ac_tags": "tag1,tag2"
},
{
"id": 14,
"ac_tags": "tag3"
}
];
join(',')
is joining the elements with a comma, but now Iād expect this:
["tag1, tag2", "tag3"];
So if Iām correct so far, where am I missing the split of ātag1ā and ātag2ā?
EDIT:
One more thing, the regex is removing all white spaces - these ones should remain intact:
,
The join is done on the map result. Itās not part of the map function.
["tag1,tag2","tag3"].join(',')
returns
"tag1,tag2,tag3"
Use replace(/\s*,\s*/g, ",")
Iām posting my appreciation so that new people might come across this extension of yours in case they missed an earlier forum post.
Dumb question: how can I install the extension? There are docs?
Edit: found itā¦
Finally used this in a project. Must say its a great time-saver. Something that Wappler could include in its arsenal permanently.
@JonL One question I have is how does using VM package affect the performance? I assume its being used for securely running the scripts, but is it costly?
Glad you found it useful.
VM does introduce some delay as it creates a new context but I run it within an IIFE to improve that.
If you want to check the overhead use some console timers in your code and make sure you forward the console output so it shows in the server log.
When you require a module it wonāt run sandboxed as it runs in its parentās context.
Do not run unsafe code.
Thanks to @sid for this contribution.
Hi! Thank you very much for this extension, Iām using it in several server apiās.
I have a small issue and I canāt figure out what exactly the cause is.
Iām using a server connect api to calculate results with code in RunJS, Iām requesting the results by sending data to perform the calculations on trough the API Action component in App Connect.
The issue is that 50% of the time RunJS returns no results. I checked the request of all empty results, and they all had the necessary data sent and there were no errors.
What could be happening in the cases where there is no result? Something related to RunJS, my code, the network or server connect?
let multipleWins = false;
let sectorArr = participants;
let prizes = prizesArr;
let winners = [];
function getWinnerChances() {
let totalChances = 0;
for (let w = 0; w < winners.length; w++) {
totalChances = totalChances + winners[w].chance;
}
return totalChances;
}
function startGame() {
for (let prize = 0; prize < prizes.length; prize += 1) {
let winningSector = randomSector();
prizes[prize].winner = sectorArr[winningSector - 1].id;
winners.push({
winner: sectorArr[winningSector - 1].id,
prize: prizes[prize].id,
chance: sectorArr[winningSector - 1].chance,
coins: prizes[prize].coins,
});
if (multipleWins == false) {
sectorArr[winningSector - 1].chance = 0;
sectorArr[winningSector - 1].radians = 0;
}
}
}
function randomSector() {
let chancesArr = sectorArr;
if (multipleWins == false) {
for (i = 0; i < chancesArr.length; i++) {
if (chancesArr[i].chance > 0) {
chancesArr[i].chance =
chancesArr[i].chance +
getWinnerChances() / (sectorArr.length - winners.length);
}
}
}
const cumulativeSum = (
(sum) => (value) =>
(sum += value)
)(0);
let newList = chancesArr.map((currElement, index) => {
let max = sectorArr[index].chance;
currElement = max;
return currElement;
});
let cumulativeList = newList.map(cumulativeSum);
let listMinMax = cumulativeList.map((currElement, index) => {
let max = currElement;
let min = 0;
if (index == 0) {
min = 0;
} else {
min = cumulativeList[index - 1];
}
currElement = { min, max };
return currElement;
});
let cSector = Math.random();
let chosenSector;
for (let i = 0; i < listMinMax.length; i++) {
if (listMinMax[i].min < cSector && listMinMax[i].max > cSector) {
chosenSector = i + 1;
break;
} else {
continue;
}
}
return chosenSector;
}
startGame();
return winners;
Hard to know.
Have you marked the āShow errorā option and checked SC logs?
Ohh sorry, I was checking the browser console and not the SC logsā¦
Failed to execute script. TypeError: Cannot read properties of undefined (reading 'id')
at startGame (RunJS:20:59)
at RunJS:87:1
at RunJS:89:20
at Script.runInContext (node:vm:141:12)
at App.exports.run (/opt/node_app/extensions/server_connect/modules/runjs.js:12:29)
at App._exec (/opt/node_app/lib/core/app.js:491:57)
at App._exec (/opt/node_app/lib/core/app.js:458:28)
at async App.exec (/opt/node_app/lib/core/app.js:427:9)
at async App.define (/opt/node_app/lib/core/app.js:417:9)
Getting this. So I guess problem with the code
Strange that it works half of the time though