Reputation: 141
I have a Dataweave script based on an example from Mulesoft https://docs.mulesoft.com/dataweave/latest/dataweave-cookbook-map-based-on-an-external-definition
I am trying to map the contents of a CSV file into an Apex object using an external field mapping. But for the sake of using the DataWeave Interactive Learning webpage I'm just trying to get it to be JSON for now.
Here is my script that I've finally got working (sort of)
%dw 2.0
input csvData application/csv
input fieldMappings application/json
input objectProperties application/json
var apexClass = objectProperties.ObjectName
output application/json
---
csvData map ((row) -> (
fieldMappings map (fieldMapping) ->
(fieldMapping.target) : if(row[fieldMapping.source] != "") row[fieldMapping.source] else fieldMapping."defaultValue")
)
The csvData is simple:
First Name,Last Name,Title,Height,Color
Jane, Austin, CEO,7,blue
Bob, Smith, COO, 6,red
My fieldMappings is likewise simple:
[
{
"source": "First Name",
"target": "FirstName"
},
{
"source": "Last Name",
"target": "LastName"
},
{
"source": "Title",
"target": "Title"
},
{
"source": "Height",
"target": "Height__c"
},
{
"source": "Importance",
"target": "Priority__c"
},
{
"source": "Interests",
"target": "Hobbies__c"
}
]
Note: I had tried a format like below, but ultimately gave up as I couldn't figure out how to iterate over each attribute
{
"First Name" : "FirstName",
"Last Name" : "LastName"
}
Anyway using the source/target concept I was able to get an output like this:
[
[
{
"FirstName": "Jane"
},
{
"LastName": " Austin"
},
{
"Title": " CEO"
},
{
"Height__c": "7"
},
{
"Priority__c": null
},
{
"Hobbies__c": null
}
],
[
{
"FirstName": "Bob"
},
{
"LastName": " Smith"
},
{
"Title": " COO"
},
{
"Height__c": " 6"
},
{
"Priority__c": null
},
{
"Hobbies__c": null
}
]
]
But what I WANT is
[
{
"FirstName": "Jane",
"LastName": " Austin",
"Title": " CEO",
"Height__c": "7",
"Priority__c": null,
"Hobbies__c": null
},
{
"FirstName": "Bob",
"LastName": " Smith",
"Title": " COO",
"Height__c": " 6",
"Priority__c": null,
"Hobbies__c": null
}
]
I've tried flatten(), I've tried to use as Object at various levels...no go.
I just recently had some success with
csvData map ((row) ->
fieldMappings map (fieldMapping) ->
(fieldMapping.target) : if(row[fieldMapping.source] != "") row[fieldMapping.source] else fieldMapping."defaultValue")
reduce ($$ ++ $)
)
but the moment I add
as Object to the end I get an error
Cannot coerce Function ((row:Any) -> ???) to Object
Anyone have any thoughts?
Upvotes: 0
Views: 37
Reputation: 141
Okay, so I guess posting the question is all I needed to find the answer. The answer was a combination of
reduce($$ ++ $)
which helped reduce the array of key/value pairs down into a single JSON object
and putting the proper parens() around the functions to include both the fieldMappings and the reduce
and then being able to put the as Object after the reduce, but before the end of the function that spits out the array of objects
Makes sense when I really think about it, but I'm new to DataWeave script and so the notion of nested functions isn't something I am familiar with.
Anyway, for those interested here is what worked:
%dw 2.0
input csvData application/csv
input fieldMappings application/json
input objectProperties application/json
var apexClass = objectProperties.ObjectName
output application/apex
---
csvData map ((row) ->
(
(
fieldMappings map (fieldMapping) ->
(fieldMapping.target) : if(row[fieldMapping.source] != "") row[fieldMapping.source] else fieldMapping."defaultValue"
)
reduce ($$ ++ $)
) as Object
)
Upvotes: 0