Manipulating and iterating over arrays

Hi @kjetil

Thank you for your thorough explanation of your case. You are right that you can do the approach you mentioned. We will also introduce the way to do it using Group Records and Operator Transformer.

Since we depend on the propId properties to define the method by comparing them between the existingOptions and newOptions arrays, we can group the objects of each array and set the propId as the key of the grouped objects.

We can do the same with the newOptions array.

This way, we will have propId-grouped objects of existingOptions and newOptions, such as below.

  "existingOptions": {
    "1": [
      {
        "propId": "1",
        "optionId": "2"
      }
    ],
    "2": [
      {
        "propId": "2",
        "optionId": "34"
      }
    ]
  },
  "newOptions": {
    "1": [
      {
        "propId": "1",
        "optionId": "2"
      }
    ],
    "3": [
      {
        "propId": "3",
        "optionId": "5"
      }
    ]
  }
}

Next, we will use Operator Transformer to map which objects need to be created, updated, or deleted.

In order to get the objects we need to create (the POST method), we should use “Array Diff Keys” operator, set the newOptions as the left path and existingOptions as the right path. We can set the Destination to a property, such as call.POST. Please see the below table.

| Method  | Operator             | Left Path       | Right Path      | Destination |
|---------|----------------------|-----------------|-----------------|-------------|
| POST    | Array Diff Keys      | newOptions      | existingOptions | call.POST   |
| PUT     | Array Intersect Keys | newOptions      | existingOptions | call.PUT    |
| DELETE  | Array Diff Keys      | existingOptions | newOptions      | call.DELETE |

We will have the below data as the result of the above Operator Transformers.

{
  "call": {
    "POST": {
      "3": [
        {
          "propId": "3",
          "optionId": "5"
        }
      ]
    },
    "PUT": {
      "1": [
        {
          "propId": "1",
          "optionId": "2"
        }
      ]
    },
    "DELETE": {
      "2": [
        {
          "propId": "2",
          "optionId": "34"
        }
      ]
    }
  }
}

Then, we should map the method, which is a key at this moment, into a property using Move data between accessors. The Source accessor should be “Key accessor” and the Root is “call”. The Destination accessor should be “Structure accessor” with “method” as the Key, “properties” as the Value, and “call” the “Root”. The result of the transformer will be such below.

{
  "call": [
    {
      "method": "POST",
      "properties": {
        "3": [
          {
            "propId": "3",
            "optionId": "5"
          }
        ]
      }
    },
    {
      "method": "PUT",
      "properties": {
        "1": [
          {
            "propId": "1",
            "optionId": "2"
          }
        ]
      }
    },
    {
      "method": "DELETE",
      "properties": {
        "2": [
          {
            "propId": "2",
            "optionId": "34"
          }
        ]
      }
    }
  ]
}

We can then copy the id property into each object in pattern call.*.properties.*.* using the Recursively copy values to children.

In order to copy the method, we should use a Node, transform nodes entity transformer using the pattern call.*. Inside the node, we can use Recursively copy values to children to copy the method property into each object using pattern properties.*.*. The entity will be such below.

{
  "call": [
    {
      "method": "POST",
      "properties": {
        "3": [
          {
            "propId": "3",
            "optionId": "5",
            "id": "1",
            "method": "POST"
          }
        ]
      }
    },
    {
      "method": "PUT",
      "properties": {
        "1": [
          {
            "propId": "1",
            "optionId": "2",
            "id": "1",
            "method": "PUT"
          }
        ]
      }
    },
    {
      "method": "DELETE",
      "properties": {
        "2": [
          {
            "propId": "2",
            "optionId": "34",
            "id": "1",
            "method": "DELETE"
          }
        ]
      }
    }
  ]
}

Finally, we can use a new Node, transform nodes entity transformer using the pattern call.*.properties.*.* and submit the HTTP request using HTTP transformer there.

I hope my explanation is clear to you. It may be not so short solution, but this is an alternative way to achieve your objective. Feel free to let me know if you have any questions.