šŸš€ RunJS 1.3.2

Update 1.2.0

Breaking Change

  • Due to wrapping the custom code in an IIFE you need to explicitly return something so it shows in the output i.e. return 'hello world'

Added

  • IIFE wrapper. Wrapped the custom code in an IIFE to improve performance of vm.
  • Forward console. You can now use console object functions in your code i.e. console.log() and the output will be forwarded to the server console.
  • UI changes

Fixed

  • Fixed initial values of several checkboxes in the UI
1 Like

@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ā€¦

  1. This is my data, from a db query:
 "query_products": [
    {
      "id": 13,
      "ac_tags": "tag1, tag2"

    },
    {
      "id": 14,
      "ac_tags": "tag3"
    }
  ],
  1. 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"];

  2. 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.)

  1. These are the settings of the plugin

  2. This is the location (in a repeat)

  3. 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 :slight_smile:

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
1 Like

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 :slight_smile:

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);
}

image

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ā€™ image . 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 :point_up:

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 :merman:

1 Like

I love one liners. Itā€™s like completing the newspaper puzzle :joy: 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 :slight_smile:

@JonL Very curious how youā€™d approach thisā€¦ Your one liner looks good but leaves me with 2 issues still:

  1. 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)

  2. 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?

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.

1 Like

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

1 Like

Thanks Jon!
May be worth mentioning how to install/setup on first post with this screenshot?

1 Like

Thatā€™s been covered in the custom extensions docs already :slight_smile: