sequential-workflow-editor icon indicating copy to clipboard operation
sequential-workflow-editor copied to clipboard

Returning or passing variables between steps

Open zacherkkila opened this issue 1 year ago • 2 comments

I appreciate your work on this library, very cool!

Just so you know, I am not sure it makes a big difference, but I am using the React designer.

I have been trying to figure out the standard way to handle this rather than building a custom variable service of some sort.

Step A - Performs a computation and stores it to a variable Step B - Uses the variable/return from the previous step

It seems that the scope is limited to the step itself when the variable is defined within the step.

image

However, I need to use the result of Step A and feed that into Step B. It is not available here

image

From the docs

When a variable is defined in the parent scope, it can be accessed in the child scope, but not vice versa.

Is the "log" step in the image not a child of the "output" step? It seems they are more treated as independent functions rather than a parent/child relationship

What is the best way to handle this scenario? Essentially a return variable from one step and use that return variable in the next step.

Output Step

interface OuputStep extends Step {
  type: 'output'
  componentType: 'task'
  properties: {
    output: NullableVariableDefinition
    showVariable: NullableVariable
  }
}

export const Output = createStepModel<OuputStep>('output', 'task', (step) => {
  step.category('Output')
  step.label('Output')
  step.property('output').value(
    createNullableVariableDefinitionValueModel({
      valueType: 'number',
      isRequired: true,
      defaultValue: {
        name: 'test',
        type: 'number',
      },
    })
  )
  step
    .property('showVariable')
    .value(
      createNullableVariableValueModel({
        isRequired: true,
        valueType: 'number',
      })
    )
    .label('Value to Log')
})

Log Step

interface ValueLogStepDef extends Step {
  componentType: 'task'
  properties: {
    valueToLog: NullableVariable
    alert: boolean
  }
}

export const ValueLog = createStepModel<ValueLogStepDef>('log', 'task', (step) => {
  step.category('Tracing')

  step
    .property('valueToLog')
    .value(
      createNullableVariableValueModel({
        isRequired: true,
        valueType: 'number',
      })
    )
    .label('Value to Log')

  step.property('alert').value(createBooleanValueModel({})).label('Alert?')
})

Definition

  const definitionModel = useMemo(
    () =>
      createDefinitionModel<T>((model) => {
        model.valueTypes(['string', 'number'])
        model.root(rootModel)
        model.steps([OutputStep, ValueLogStep])
      }),
    []
  )

Thank you very much!

zacherkkila avatar May 23 '24 14:05 zacherkkila

Hello @zacherkkila!

Is the "log" step in the image not a child of the "output" step?

I think you understand differently the "child" term than the documentation describes (maybe the documentation is not too precise).

The child means a step inside a step, like:

|__ loop { defines x }
|   |_ setAddress { x = 127.0.0.1 }
|   |_ ping1 { use x } // OK
|
|_ ping2 { use x } // ERROR

In the above example ping1 has the access to the x variable defined by the loop step. The ping2 step DOES NOT have the access to the x variable. You can try to represent it using some abstract programming language:

section (x = null) {
   x = 127.0.0.1
   ping(x) // OK
}
ping(x) // ERROR

In the case from your example you can solve this problem by:

  • define the "x" variable by the root editor,
  • select the "x" variable in the "output" property of the "output" step,
  • select the "x" variable in the "valueToLog" property of the "valueLog" step.
interface MyDefinition extends Definition {
   properties: {
      myVariables: VariableDefinitions;
   // ...
}

interface OuputStep extends Step {
   properties: {
      output: NullableVariable;
   // ...
}

interface ValueLogStep extends Step {
   properties: {
      valueToLog: NullableVariable;
   // ...
}

I reccomend to check the source code of this demo.


Another thing is that, I understand the need that some step may produce an output for a next step. This behaviour I noticed in Zapier. The Sequential Workflow Editor doesn't support this behaviour, but maybe this is something that is worth to consider for the pro version.

b4rtaz avatar May 24 '24 10:05 b4rtaz

Thank you for the response!

The Sequential Workflow Editor doesn't support this behaviour, but maybe this is something that is worth to consider for the pro version

I do think this would be a useful add.. Just to give an idea of the feature we are building:

  • Input data is fed into the workflow
  • We allow users to create a workflow to run operations on this input data
  • Save steps are available to create data from the above operations (something like a min fee or logic based discount calculation)

Zapier is a good parallel here, though entirely different use case for us

Thank you for the recommendations, we should be able to make something work here with that info!

zacherkkila avatar May 24 '24 15:05 zacherkkila