Search code examples
muledataweavemulesoftmule4

Filtering based on a value inside array of object using DataWeave 2.0


Below is my input JSON

{
"context": "context",
"meetings": [
    {
        "id": 123,
        "subject": "subject 123",
        "attendees": [
            {
                "type": "required",
                "emailAddress": {
                    "name": "user1",
                    "address": "[email protected]"
                }
            },
            {
                "type": "required",
                "emailAddress": {
                    "name": "!user2",
                    "address": "[email protected]"
                }
            }
        ]
    },
    {
        "id": 456,
        "subject": "subject 456",
        "attendees": [
            {
                "type": "required",
                "emailAddress": {
                    "name": "user3",
                    "address": "[email protected]"
                }
            },
            {
                "type": "required",
                "emailAddress": {
                    "name": "user4",
                    "address": "[email protected]"
                }
            }
        ]
    }
]
}

From the above JSON, First, I want to filter out the objects where name of the user starts with ! and in each resultant object, I want to add a new attribute email where email is the email of the attendee whose name starts with !. Below is my expected output:

[
{
"id": 123,
"subject": "subject 123",
"attendees": [
            {
                "type": "required",
                "emailAddress": {
                    "name": "user1",
                    "address": "[email protected]"
                }
            },
            {
                "type": "required",
                "emailAddress": {
                    "name": "!user2",
                    "address": "[email protected]"
                }
            }
        ],
"email" : "[email protected]"
}
]

I am completely new to DataWeave. can someone please help me in getting the expected output.

I tried with the below code

%dw 2.0
output application/json
---
payload.meetings filter ((item, index) -> item.attendees.emailAddress.name startsWith  "!") map (
{
  "id" : $.id,
  "subject" : $.subject,
  "attendees" : $.attendees,
  "email" : ($.attendees filter $.emailAddress.name startsWith  "!")[0].emailAddress.address
})

But it turned out to be below error :

You called the function 'startsWith' with these arguments: 
  1: Array (["user1", "user2"])
  2: String ("!")

But it expects arguments of these types:
  1: String
  2: String

4| payload.meetings filter ((item, index) -> item.attendees.emailAddress.name startsWith  "!") map (

Solution

  • I guess this script would help you.

    Input

    {
    "context": "context",
    "meetings": [
        {
            "id": 123,
            "subject": "subject 123",
            "attendees": [
                {
                    "type": "required",
                    "emailAddress": {
                        "name": "user1",
                        "address": "[email protected]"
                    }
                },
                {
                    "type": "required",
                    "emailAddress": {
                        "name": "!user2",
                        "address": "[email protected]"
                    }
                }
            ]
        },
        {
            "id": 456,
            "subject": "subject 456",
            "attendees": [
                {
                    "type": "required",
                    "emailAddress": {
                        "name": "user3",
                        "address": "[email protected]"
                    }
                },
                {
                    "type": "required",
                    "emailAddress": {
                        "name": "user4",
                        "address": "[email protected]"
                    }
                }
            ]
        }
    ]
    }
    

    Code

    %dw 2.0
    import * from dw::util::Values
    import * from dw::core::Arrays
    var filteredInput = (payload.meetings update "attendees" 
                            with (if ($.emailAddress.name some ($ startsWith  "!")) $ 
                                  else null )) filter $.attendees != null
    output application/json 
    ---
    filteredInput map {
      Id: $.id,
      subject: $.subject,
      attendees: $.attendees map {
        "type": $."type",
        emailAddress: $.emailAddress
      },
      email: do{
          var email =  ($.attendees.emailAddress filter ($.name startsWith  "!")).address
          ---
          if(sizeOf(email) == 1) email[0] else email
      }
    }
    

    Output

    [
      {
        "Id": 123,
        "subject": "subject 123",
        "attendees": [
          {
            "type": "required",
            "emailAddress": {
              "name": "user1",
              "address": "[email protected]"
            }
          },
          {
            "type": "required",
            "emailAddress": {
              "name": "!user2",
              "address": "[email protected]"
            }
          }
        ],
        "email": "[email protected]"
      }
    ]
    

    In case only one name has the "!" character, the email will be a string, if there is more than one match, it will be an array.