Split JSON Array to an Object - mule

I have a payload like below:
{
"data": [
{
"id": "f251f05f-038c-4c26-bf7c-3b2fc47210e6",
"specialtyIds": [
"20c5f3f0-54c9-4779-b1a3-19baeee91b4a"
]
},
{
"id": "61d34a84-940d-4556-9c4b-ef7bede9caca",
"specialtyIds": [
"20c5f3f0-54c9-4779-b1a3-19baeee91b4a",
"9834e1cf-94c4-4188-83e6-867ac1d60017",
"30d6g4d3-54c9-4779-b1a3-19baeee92cdc"
]
}
]
}
and want to return an array like:
[
{
id: "20c5f3f0-54c9-4779-b1a3-19baeee91b4a"
},
{
id: "9834e1cf-94c4-4188-83e6-867ac1d60017"
},
{
id: "30d6g4d3-54c9-4779-b1a3-19baeee92cdc"
}
]
I've used the following dataweave which works fine when specialtyIds is only one element. But the second there's more than one element it breaks:
payload.data map {
id: $.specialtyIds joinBy(",")
} distinctBy $
if the array has more than two elements the script returns:
[
{
id: "20c5f3f0-54c9-4779-b1a3-19baeee91b4a"
},
{
id: "20c5f3f0-54c9-4779-b1a3-19baeee91b4a,9834e1cf-94c4-4188-83e6-867ac1d60017"
}
]
I am relatively new to dataweave, but have explored pluck and reduce to iterate over the arrays but haven't had much luck. I feel like there is probably a simpler way to tackle this structure.

This script gets the last element of each specialityIds arrays and returns the exact output that the question shows as the expected output.
%dw 2.0
output application/json
---
flatten(payload.data.*specialtyIds) map {id: $}

It looks quite simple, not sure if I am answer correctly, here the solution
payload.data.map(item => ({id: item.specialtyIds.join(", ")}))
and you can do the following for ", " without space after (ps: you can't have "," as join, so join() will give you "," by default)
payload.data.map(item => ({id: item.specialtyIds.join()}))
Run from Console

Try this,
%dw 2.0
output application/json
flatten(payload.data.*specialtyIds) distinctBy $ map ({
id: $
})

I think the solution will meet all your requirements:
%dw 2.0
output application/json
---
flatten(flatten(payload.data.specialtyIds) map ( $ splitBy ",")) distinctBy $ map ({ id: $ })

Related

Splitting concatenated values in table column using Dataweave

I have sample data in my Salesforce table as given below:
I am on Mule 3.9 and running dataweave 1.0.
I need to use dataweave to read the above data (from a Salesforce table) and transform it into a JSON as given below:
[
{"Id": "634594cc","Name": "Alpha","List": "AB01"},
{"Id": "634594cc","Name": "Alpha","List": "AB02"},
{"Id": "634594cc","Name": "Alpha","List": "AB03"},
{"Id": "5d839e9c","Name": "Bravo","List": "CD01"},
{"Id": "5d839e9c","Name": "Bravo","List": "CD02"},
{"Id": "3a5f34d3","Name": "Charlie","List": null}
]
As you can see above, the "List" column is what I need to split as separate arrays in the final JSON. It has data with semicolon at the begin, in between and in the end.
Thanks in advance for your help.
I took the liberty to create a couple of sample data based upon the SS (BTW, its best not to use SS) :).
Try this:
%dw 1.0
%output application/dw
%var data = [
{
id: "ABC123",
name: "A",
list: ";AB1;AB2;AB3;"
},
{
id: "ZXY321",
name: "B",
list: null
}
]
---
data reduce (e,result=[]) -> (
result ++ using (
list = e.list default "" splitBy /;/ filter ($ != ""),
sharedFields = {
Id: e.id,
Name: e.name
}
) (
using (
flist = list when ((sizeOf list) > 0) otherwise [null]
) (
flist map {
(sharedFields),
List: $
}
)
)
)

how to get string values from list of maps in dataweave 2.0?

I have input payload coming like this -
[
{
"a": ""
},
{
"a": "abc"
},
{
"a": "pqr"
},
{
"a": "xyz"
}
]
and desired output is abc,pqr,xyz
I tried following dwl but couldn't succeed. Here is the code snippet
%dw 2.0
output application/json
query : payload filter ($.a != '') map (
$.a
)
Can someone please help me with the dataweave ? Thanks.
If your desired output is the string "abc,pqr,xyz":
%dw 2.0
output application/json
---
payload filter ($.a != "") map ($.a) joinBy ","
If you are trying to get the array ["abc", "pqr", "xyz"]:
Your code is fine...
%dw 2.0
output application/json
---
payload filter ($.a != "") map ($.a)
query: joinBy(payload.a filter $ !="", ',')
First select all 'a' fields to return new array of just values.
Filter the list for "".
Use joinBy function to append array values with a comma.

mule : how to convert list of maps to list of JSon in dataweave?

I have input data as list of maps like [{id="200" name="aaa"},{id="100",name="shbd"}].
I want to transform it to JSON like below
{
[
{
id="200",
name="aaa"
},
{
id="100",
name="shbd"
}
]
}
If the fields(keys in map) do no change, then it is simple and straightforward. Now how to transform if I dont know the key values. For eg, what if after sometime the input of map is [{"age":90},{"age","45"}]
It's always better to do specific mapping but you can go with the following , it will transform it into JSON
%dw 1.0
%output application/json
---
payload
As Anirban said, please validate the json you want to transform.
You can use below transformation for o/p specified below:
Transformation
---------------
%dw 1.0
%output application/json
---
payload map {
"id" : $.id,
"name" : $.name
}
---------------
expected output
--------------
[
{
id="200",
name="aaa"
},
{
id="100",
name="shbd"
}
]

Merge two JSON outputs into one with Dataweave

I currently have two JSON files with data.
The first has a list of actions by a user. However, the userID is a UID string instead of their user name.
The second is a JSON list of UID strings with their corresponding user names. I stored this JSON in a Flow Variable named UserPayload
I'd like to merge the user name into the first list so that my output has actual users names instead of the UID.
Here is what I had so far...but the userId part doesn't work since my flowVar is an list.
%dw 1.0
%output application/csv
---
payload map ((payload01, indexOfPayload01) -> {
user: payload.01.userId,
actions: payload01.action,
FileName: payload01.payload.properties.name default "N/A",
userId: flowVars.UserPayload.objectName
})
Any help would be appreciated. Thanks!
you can access the right object from the UserPayload flowVar by either filtering the content of UserPayload based on userId or creating a associative array from UserPayload.
filtering UserPayload
%dw 1.0
%output application/json
---
payload map (action, index) -> {
user: action.user,
action: action.action,
FileName: action.FileName,
userId: (flowVars.UserPayload filter $.objectId == action.user)[0].objectName
}
associative array
%dw 1.0
%output application/json
%var users = flowVars.UserPayload groupBy $.objectId
---
payload map (action, index) -> {
user: action.user,
action: action.action,
FileName: action.FileName,
userId: users[action.user][0].objectName
}
for my examples i used following sample data derived from your question.
flowVars.UserPayload
[{
"objectId": "0000-0000-0001",
"objectName": "first user"
}, {
"objectId": "0000-0000-0002",
"objectName": "second user"
}]
payload
[{
"user": "0000-0000-0001",
"action": "some crazy action",
"FileName": "some-crazy-action.mov"
}]

How to get unnamed object instead of an array in case of only one result in Dataweave

We have a transformation with Dataweave which processes a list of objects. We get a json response like that:
{"hotels": [{
"name": "Hotel Oslo",
"propertyCode": "12345",
"currency": "NOK"
},
{
"name": "Hotel Stockholm",
"propertyCode": "12346",
"currency": "SEK"
}]}
However, in the case of only 1 response, we want to have the following response:
{"name": "Hotel Stockholm",
"propertyCode": "12346",
"currency": "SEK"}
We are generating the response like this:
{
hotels: payload.rows map ((row , indexOfRow) -> {
name: row.content.companyName.content,
propertyCode: row.content.propertyCode.content,
currency: row.content.currencyCode.content
})}
What should we put as a condition so that we do not get an array in case of 1 result?
Try this:
%dw 1.0
%output application/json
%function makeHotel(row) {
name: row.name,
propertyCode: row.propertyCode,
currency: row.currency
}
---
{
hotels: payload.rows map ((row , indexOfRow) -> makeHotel(row))
} when ((sizeOf payload.rows) != 1)
otherwise makeHotel(payload.rows[0])
It will give you an empty array on empty input, the simple object for one input and the structure with array when you have more than one input row.
(For test purposes, with a slightly differnt input structure, but the general solution should be clear.)