Transform list of objects into csv using dataweave - mule

I am trying to transform a list of objects to csv using the following code in dataweave:
%dw 1.0
%type company = :object {class: "java.util.ArrayList"}
%input payload application/java
%output application/csv
---
{
name: payload.name,
address: payload.address
} as :company
The below is the output that I get when I execute the above data weave code.
name,name
testName,testName2
testAddress,testAddress2
whilst I am expecting the following: (Sample data)
name,address
testName,testAddress
testName2,testAddress2
Help me understand to what am I missing in the data weave component

In general terms, when using DataWeave you describe your output using a canonical representation which is more or less a super-set of other data formats.
To generate a CSV output you need to generate an array of objects.
Each of these objects represent a CSV row.
Objects in DataWeave are sets of key-value pairs
The mapping should be something like:
%dw 1.0
%output application/csv
---
payload map {
name: $.name,
address: $.address
}
The map operation here generates an object with a name and address for each entry in the list. $ represents the implicit variable under iteration (each list entry).
Note: The %input payload application/java directive is not necessary since the content-type for your input (JSON, XML, CSV, etc) is taken from the mule message when it is set, and it defaults to java if it's not present.

The following works for me:
INPUT:
%dw 1.0
%output application/java
---
[{
name: "nameInput",
address: "addressInput"
}]
MAPPING:
%dw 1.0 %output application/csv
---
payload
OUTPUT:
name,address
nameInput,addressInput

A splitter with xpath as evaluator should do the trick...like:
<splitter evaluator="xpath" expression="/document/article"/>

For me, similar as #Tilo descirbed in his post, but I had to put extra "flatten" because I had Array of Arrays as my input.
MAPPING:
%dw 1.0
%output application/csv
---
flatten payload

Related

Dynamically reference payload field names in Dataweave

I am using Anypoint Studio 7.3 and Mule 4.1.
I am looking to dynamically pass the field name from a JSON payload when transforming a message so on the 1st call I want to use the values in the "cat_name" field and when I call it a 2nd time I want to use the values in the "dog_name" field as the output message structure will be the same. So for "cat_name" I would want $.(vars.codetest) to be resolved as payload.cat_name and for "dog_name" I would want $.(vars.codetest) to be resolved as payload.dog_name
Is there a way of doing this?
%dw 2.0
output application/json
---
(payload distinctBy $.#[vars.codetest]) map ((payload01, indexOfPayload) ->{
name: $.(vars.codetest)
})
Thanks for any help
Something like this should work:
%dw 2.0
output application/json
---
payload
distinctBy $[vars.codetest]
map ((element) -> { name: element[vars.codetest] })
You might need parens around codeTest (i.e. (vars.codetest)) so that it gets evaluated before the lookup.

How to convert list hashmap into Array using Dataweave

I have list as below
[{customerId="123"},{customerId="456"},{customerId="786"}]
I want to convert above as Array like below
[123,456,786]
Can you please help on how to achieve using dataweave
Following code will return array
%dw 1.0
%output application/java
---
payload.customerId map $ as :number
Please refer dataweave-selectors for more details.

Mulesoft Dataweave convert CSV to map dynamically

I've created a flow that accepts a CSV via a form-data API POST and then processes each row in a batch job. Ideally, I do not want to hand-map each column before passing it to the batch executor, but I could not figure out how to just "pass through" the key/value pairs dynamically. I want to ensure that the CSV can have new columns and we'll pass them through without knowing about them beforehand... This is what I have:
%dw 1.0
%output application/java
---
payload map {
title: $.title,
description: $.description,
template_id: $.template_id,
pricing_flat_price: $.pricing_flat_price,
scheduled_start_date: $.scheduled_start_date,
resource_id: $.resource_id,
industry_id: $.industry_id,
owner_email: $.owner_email,
location_offsite: $.location_offsite
}
And this is what I'm going for (in non-sensical psuedocode):
%dw 1.0
%output application/java
---
payload map {
*:*
}
I have to imagine this is easily done, but I couldn't figure it out.
Thank you,
Steve
You can simply use transformation like below -
%dw 1.0
%output application/java
---
(payload)
hand-map each column before passing it to the batch executor
You shouldn't need to do this. Pass the whole csv to the batch-input phase and allow it to split each line into a Linked Hashmap.

Converting CSV to array using DataWeave

I'm using Mule Requester to load a CSV file. After the file is loaded, the payload is a byte array, which I store in a flow variable, mycsv. I keep getting an exception.
org.mule.api.MessagingException: Exception while executing:
NetIds: flowVars.mycsv map $."My Column Name"
^
Cannot coerce a :binary to a :array (com.mulesoft.weave.mule.exception.WeaveExecutionException). Message payload is of type: byte[]
Here's my DataWeave code:
%dw 1.0
%output application/java
---
{
Values: flowVars.mycsv map $."My Column Name"
}
The previous flow element is a choice, so I set the metadata on that to output to a FlowVar with the right name and referenced a sample CSV file, so DataWeave things the variable type is List<Csv>.
How can I read the CSV? Thanks!
It's because it doesnt know the mimeType of the flowVar because it's not set. Try this before the dataweave transformer:
<set-variable value="#[flowVars.mycsv]" variableName="mycsv" mimeType="application/csv" doc:name="Variable" />
or set the mimeType when you first read the csv.
This is the first time I found a requirement to put two different formats into one csv file. In order to get the expected result, I prefer to use this trick:
Create both expressions and combine them into one simple array, using flatten
Add an empty object as line separator

How to refer payload which is a ResultSet Iterator in mule dataweave?

Sql query returns a streamed output as Resultset iterator object from the Database component.
i want to convert this to xml in dataweave. But don't know how to refer the incoming object,
If it's a map i can access it simply by using .operator like payload.student
Tried using payload.next() but it gives an error. Also tried the following,
%var input1 payload as :iterator but still wont' work
Here the steps:
Drag and drop the Transform Message (Dataweave) component after your configured DB Connector. You will see that the input payload for dataweave script is filled with the db result List<Map>.
Then you can access the fields, using the map function in dw.
dw script
%dw 1.0
%output application/xml
---
{
"Results":{
(payload map {
"key1":$."db_field1",
"key2":$."db_field2"
})
}
}
Can you post your code (XML) and a screenshot of dataweave or debugger?
My first guess would be to use a standard transfomer to transform that object to a list or map before the dataweave transformer.