muledataweave

Is there a DataWeave "for" operator?


I would like to create as many elements as a count variable specifies, for example:

There is a table that has information about supported equipment

select port_count 
from equipment
where id=#[flowVars.equipmentId]

And I've to generate a message that another system out of my control interprets and executes (DataWeave 1.0):

<dw:transform-message doc:name="Get value">
    <dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
  "actions": {
    (for 1..flowVars.port_count map {
      "action": {
        "type": "add_port",
        "id": $$
      }
    })
  }
}]]></dw:set-payload>
</dw:transform-message>

Desired result:

{
  "actions": {
    "action": {
        "type": "add_port",
        "id": 1
    },
    "action": {
        "type": "add_port",
        "id": 2
    }
  }
}

Solution

  • DataWeave has no concept of for because it is a functional language. Still you can what you want by using a range instead:

    DataWeave 2.x

    %dw 2.0
    var port_count=3
    output application/json
    ---
    {
      actions: 
        if (port_count > 0) 
            ((1 to port_count) as Array 
                map
                    action: {
                        "type": "add_port",
                        "id": $
                    }
            ) reduce ((item, accumulator={}) -> accumulator ++ item )
        else [] 
    }
    

    DataWeave 1.x

    %dw 1.0
    %var port_count=3
    %output application/json
    ---
    {
      actions: 
        (((1 to port_count) when port_count > 0 otherwise []) map
          action: {
            "type": "add_port",
            "id": $
          }
        )  reduce ($$ ++ $)
    }
    

    Output:

    {
      "actions": {
        "action": {
          "type": "add_port",
          "id": 1
        },
        "action": {
          "type": "add_port",
          "id": 2
        },
        "action": {
          "type": "add_port",
          "id": 3
        }
      }
    }
    

    Just change the port_count variable for the flowVar and you will be all set.

    Removing the reduce() operator will return an array instead, which would make more sense to me.