How to concatenate two arrays into one in Server Actions? (NodeJS)

For instance, I have [1,2] and [3,4].
How to get a [1,2,3,4] ?

There is concat method in JS. Is there something similar in Wappler?

Have you checked:

Yes, but I couldn’t understand how to apply it to simple arrays like [1,2] and [3,4]

Where do these value come from?

In the current case I wanna create a variable that would be an array and then add the numbers to it during some repeat operations. After all I would use this array of numbers in some validations.

So, actually I need an “add number to array” method.

But array concatenation would work too, so I wanna learn this too. It would be helpful anyway.

So these are two set value steps holding values or?

Well, I have a repeat, that uses some data from DB.
Each cycle inside the repeat some number generated.
When it is generated I need to add it to the array outside the repeat. Let’s call this variable “MyGlobalArray”.
(It need to be added instantly and not after the repeat is ended, because “MyGlobalArray” itself is used inside repeat)

So I think that inside the repeat it would be step Set Value that sets/changes “MyGlobalArray” = “MyGlobalArray” ADD “some new number”.

E.g “MyGlobalArray” = [23, 45, 67],
“some new number” = 89,
so “MyGlobalArray” after change should be [23, 45, 67, 89]

To answer you question, if my assumption about how it should work is correct, then it would be only one Set Value. One that sets/changes “MyGlobalArray”.

So basically I managed to configure the kind-a-solution for CONCAT [1,2] and [3,4]

  1. Convert arrays to String
  2. Concatenate strings together
  3. Split the string to array
  4. Make a repeat and inside of it set a variable, that takes $value and convert it to number.
  5. Apply flatten for repeat

I like puzzles, but I believe that there must be a more elegant solution for this in Wappler. :slight_smile:

1 Like

Sometimes I wish there was a step to run pure JavaScript code for stuff like this (without custom modules)

You could probably build a custom module(yeah I know…) based on eval(), anonymous functions or even better(and safer) vm2 to run whatever js code you need as a step.

It could be a cool extension and fun to build. I might even give it a try at some point.

Something like this?

Below you have a rough and quick approach. Unfortunately I don’t have much time to work on this but maybe you want to take a go at it if you really need it. There would be a lot of parsing and token filtering required but it’s doable as you can see above.

const { NodeVM } = require('vm2')
const Parser = require('../../../lib/core/parser');
exports.run = function (options) {
    let tokens = (Parser.lexer(options.code))
    let result = []
    tokens.forEach(function (e) {
        if (e.name === 'L_CURLY' || e.name === 'R_CURLY') {
        }
        else if (e.name === 'IDENT') { result.push(JSON.stringify(this.scope.get(e.value))) }
        else {
            result.push(e.value)
        }
    }.bind(this))
    let code = result.join('')
    const vm = new NodeVM();
    return vm.run('module.exports =' + code)
}
1 Like

Uh Jon that is way over complicated.

A simple concat formatter should do just fine @patrick

LOL @George I know. This is not a solution for concat but for:

Ah i see :slight_smile: well we deliverable disallow running any JavaScript in expressions because this can cause security issues.

Indeed it can.

That’s the reason why I selected VM2 as module for it.

1 Like

Aha I see, good idea indeed instead of just eval.
Good to be sandboxed.

1 Like

Thanks for kick-starting! I’ll take a look at it soon, some scary words there, “lexer” :smiley:
(no idea why we need to go such deep to the point of parsing actual strings)

My idea is more like allowing a snippet of JS, like this:

let array1 = [1, 3];
let array2 = [4, 5];
return array1.concat(array2);

Can’t we just call vm.run(whatever_in_textarea)? And in Wappler it would be a textarea instead of single-line input of code.

Pseudo-code of module:

function runCustomCode(snippet) {
    // Wrap snippet inside function()
    let code = "function() {" + snippet + "}()";
    // Run function, and return function result to Wappler
    return vm.run(code)
}

Yes, you can call whatever you want from the text area but wouldn’t you want to reference values stored in Server Connect via the Server Bindings?

Yes, so I need to call this.parse(snippet)? Or do I need that whole token parser thing?