workflow-es icon indicating copy to clipboard operation
workflow-es copied to clipboard

Can't make make sequential for loop

Open vimalraj-a opened this issue 7 years ago • 6 comments

I need to run few set of steps in sequentially inside for-each. Current ForEach step is parallel step. Sometimes I might need to load the collection dynamically (based on external web service).

Is it possible to make for-each as sequential?

vimalraj-a avatar Jan 03 '19 16:01 vimalraj-a

are you able to achieve the same thing with a .while step? we would need to implement a new feature to support a serialized for-each

danielgerlag avatar Jan 05 '19 17:01 danielgerlag

I can use while step. But It makes the workflow data dirty when we have 3-4 loops and inner loops.

vimalraj-a avatar Jan 06 '19 08:01 vimalraj-a

@danielgerlag I found a way to create custom step for my scenario. Its working fine for my need. Can you suggest any better way to handle the sequential for?

sequential-for-each.ts

export class SequentialForEach extends ContainerStepBody {
  public collection: any[];
  public data: any;

  public run(context: StepExecutionContext): Promise<ExecutionResult> {
    if (!context.persistenceData) {
      if (this.collection && this.collection.length) {
        let containerData = new LoopData();
        containerData.childrenActive = true;
        containerData.idx = 1; // Because 0th item will be processed here
        return ExecutionResult.branch([this.collection[0]], containerData);
      } else {
        return ExecutionResult.next();
      }
    }

    if ((context.persistenceData as LoopData).childrenActive) {
      let complete: boolean = true;

      for (let childId of context.pointer.children)
        complete = complete && this.isBranchComplete(context.workflow.executionPointers, childId);

      if (complete) {
        if (context.persistenceData.idx < this.collection.length) {
          const item = this.collection[context.persistenceData.idx++];
          return ExecutionResult.branch([item], context.persistenceData);
        } else {
          return ExecutionResult.next();
        }
      } else return ExecutionResult.persist(context.persistenceData);
    }

    return ExecutionResult.persist(context.persistenceData);
  }
}

vimalraj-a avatar Jan 24 '19 08:01 vimalraj-a

That looks like it would work 👍 Nice to see people implementing their own primitives like this 😄

danielgerlag avatar Jan 25 '19 03:01 danielgerlag

Does it work on empty collections?

danielgerlag avatar Jan 25 '19 15:01 danielgerlag

It will work with empty array and null as well. Check 2nd line of run method.

vimalraj-a avatar Jan 25 '19 19:01 vimalraj-a