šŸš€ RunJS 1.3.2

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, '')
  1. (e) = current processed element, so in the first run that would be:
{
      "id": 13,
      "ac_tags": "tag1, tag2"
    }
  1. The arrow notation is short for:
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.

  1. Weā€™re still in the map, so itā€™s doing this for each object in the array. So now we have:
let tags = [
    {
      "id": 13,
      "ac_tags": "tag1,tag2"
    },
    {
      "id": 14,
      "ac_tags": "tag3"
    }
  ];
  1. The 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:


(I guess I can tweak the RegEx but that is a confusing subject that I really need to invest more time in at some point in my life)

, :slight_smile:

1 Like

The join is done on the map result. Itā€™s not part of the map function.

["tag1,tag2","tag3"].join(',')

returns

"tag1,tag2,tag3"

1 Like

Use replace(/\s*,\s*/g, ",")

1 Like

Iā€™m posting my appreciation so that new people might come across this extension of yours in case they missed an earlier forum post.

Thank you, @JonL & @Apple

1 Like

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. :+1:

@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.

1 Like

Update 1.3.0

Added

  • Added an option to run your code asynchronously
  • Added an option to require modules from your code

Warning

When you require a module it wonā€™t run sandboxed as it runs in its parentā€™s context.
Do not run unsafe code.

Acknowledgement

Thanks to @sid for this contribution.

Update 1.3.1

Fixed

  • Fixed Async wrapper for the main function

6 Likes

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

1 Like

BTW I am glad you are finding it useful. Sometimes I would love to know how many people use it :slight_smile:

1 Like

Iā€™m using it in like 7 server connect apiā€™s, really useful. Iā€™m very new to Javascript so making modules would be much more complicated for me, this makes it easy for beginners to do stuff

1 Like

For all of you that are using this extension you might want to vote for this Feature Request:

The actual multiline field is less than ideal for coding :slight_smile:

Problematic function might be random sector

Error occurs in start Game in this line:
prizes[prize].winner = sectorArr[winningSector - 1].id;

Specifically after the equal sign

1 Like

Hi! Like half of the data wasnā€™t formatted correctly so whenever the random pick was in the incorrect half of the data it was throwing the error. Thatā€™s why it was working half of the timešŸ˜… Now with correct data all works. Thanks for taking the time to look trough it

Dose this give us the ability to use npm packages ?

Please please say yes :raised_hands:t5: Lol.

Yes you can.

You can also use node packages with custom extensions.

Could you add an option to actually throw an error? Right now, if thereā€™s a script error, steps proceed anyway, which is undesirable in case of an error

1 Like