Loop through array!

Post Reply
MY001
Newbie
Posts: 9
Joined: Mon Feb 15, 2021 9:47 pm

Loop through array!

Post by MY001 »

I am little bit confused how Switch scripting works. I read in a post that the when the job arrives to a scripting step, the sendToSingle function does not execute until script is fully done. What I am trying to achieve is that I have jobs in form of xml and within the xml theres a metadata contain a list of urls and I want to loop through those links and send each of them as a job and attach privatedata for alter call to be downloaded.

The issue I am encountering is that is that when I loop through array with "For" method, it always returns the last element of the array and it send the jobs to next outgoing flow with the last element of the array in all jobs

Let's for example say I have an array of ["Url1", "Url2","Url3"] , Switch sends 3 jobs and all of them carry privatedata of "Url3" while I want 3 jobs and each of them have a privatedata if url1 for 1st, url2 for 2nd and url3 for 3rd.

I tried different ways by adding index to the loop so the index will increase with every loop but I still get same result .

Below is one of the codes that that I tried
async function jobArrived(s,flowElement,job){

let links= await parseXPathAsString("file","/JSON/array/urls",job);
let cleanURLs= links.match(/\bhttps?:\/\/\S+/gi);


for(let i = 0; cleanURLs.length > i; i++) {
if (cleanURLs.indexOf('dropbox') != -1){
cleanURLs = cleanURLs.replace('dl=0', 'dl=1');

}

await job.setPrivateData("Link",cleanURLs);

await job.sendToSingle(job.get());
}
}


Any idea how to achieve looping through the Urls in the array and send amount of job based on how many urls exists in the array and each job MUST carry one url out of the array and have it as privatedata?

Thank you
borisCM
Member
Posts: 37
Joined: Mon May 06, 2019 12:23 pm
Location: Netherlands

Re: Loop through array!

Post by borisCM »

Hi,

i have not tested it but i think like this it should work:

inside the loop you will need to make child jobs Job.createChild(path: string): Promise<Job>
and than also in the loop you will need to set the private data for each child jobs Job.setPrivateData(tag: string, value: string): Promise<void>
also in the loop you will need to send the new created child jobs to the output with Job.sendToSingle(newName?: string): Promise<void>

after the loop you will need to send the original job to null, because you don't need it anymore.

hope this helps

kind regards
borisCM
Member
Posts: 37
Joined: Mon May 06, 2019 12:23 pm
Location: Netherlands

Re: Loop through array!

Post by borisCM »

this a simple working example

Code: Select all

async function jobArrived(s: Switch, flowElement: FlowElement, job: Job) {

    let numberOfJobs:number = 5
    let jobPath:string = await job.get(AccessLevel.ReadOnly);

    for (let jobs:number = 1; jobs <= numberOfJobs; jobs++){
        let childJob:Job = await job.createChild(jobPath);
        await childJob.setPrivateData("number",jobs.toString())
        await childJob.sendToSingle(jobs + ".xml");
    }
await job.sendToNull
}
stargazerllc
Newbie
Posts: 12
Joined: Mon Jan 25, 2021 8:24 pm

Re: Loop through array!

Post by stargazerllc »

Using the array functions instead of for each might be a better solution. The most common are .map(), .forEach() and .reduce()

Reference https://developer.mozilla.org/en-US/doc ... ects/Array

Code: Select all

 const myArr = [val1, val2, val3]
 
 const functionThatProcessesEachValueIndividually = (value)=>{
 // do something to the individual value of the array that is passed into this function.

 }

// performs actions on each element of array
myArr.forEach(functionThatProcessesEachValueIndividually)
 
 // performs actions and puts the return values in the place of the element. 
const newValues = myArr.map(functionThatProcessesEachValueIndividually)

// this would replace your for loop
const replacerFunction = (url) => url.replace('dl=0', 'dl=1')
const replacedUrls = cleanURLs.map(replacerFunction)
// which can also be written as 
const replacedUrls = cleanURLs.map((url) => url.replace('dl=0', 'dl=1'))

Post Reply