DataWeave unflatten mapping - mule

Need some help in writing DataWeave for this Salesforce payload.
Please help with creating a DataWeave for this input and expected output.
INPUT
[
{
"Order": {
"Account_Name__c": "test danish 002",
"Id": "8018s000004mpqjAAA",
"type": "Order"
},
"UnitPrice": "13.45",
"Product2": {
"Id": null,
"type": "Product2",
"Name": "* 1 LEG FOR MESAHORNO STAND110"
},
"Id": "8028s000000kyUDAAY",
"type": "OrderItem",
"OrderItemNumber": "0000051590"
},
{
"Order": {
"Account_Name__c": "test danish 002",
"Id": "8018s000004mpqjAAA",
"type": "Order"
},
"UnitPrice": "308.45",
"Product2": {
"Id": null,
"type": "Product2",
"Name": "* 2 Uprights incl castors f RTWZ 600 Var"
},
"Id": "8028s000000kyUEAAY",
"type": "OrderItem",
"OrderItemNumber": "0000051591"
},
{
"Order": {
"Account_Name__c": "test danish 002",
"Id": "8018s000004mpqjAAA",
"type": "Order"
},
"UnitPrice": "31.0",
"Product2": {
"Id": null,
"type": "Product2",
"Name": "* 25 Comp Glass Rack - 3 Ext - Red Base"
},
"Id": "8028s000000kyUFAAY",
"type": "OrderItem",
"OrderItemNumber": "0000051592"
},
{
"Order": {
"Account_Name__c": "test danish 002",
"Id": "8018s000004mpqjAAA",
"type": "Order"
},
"UnitPrice": "31.65",
"Product2": {
"Id": null,
"type": "Product2",
"Name": "* 36 Comp Glass Rack 3 Ext - Gray"
},
"Id": "8028s000000kyUGAAY",
"type": "OrderItem",
"OrderItemNumber": "0000051593"
}
]
This is the Salesforce Query on OrderLineItems but the transformed payload needs to be done on Order Object
and the output would look like
Output
{
"Id":"8018s000004mpqjAAA",
"Order Name": "test danish 002",
"Line Items": [
{
"Id":"8028s000000kyUDAAY",
"ItemNumber":"0000051590",
"Name":"* 1 LEG FOR MESAHORNO STAND110"
},
{
"Id":"8028s000000kyUEAAY",
"ItemNumber":"0000051591",
"Name":"* 2 Uprights incl castors f RTWZ 600 Var"
},
{
"Id":"8028s000000kyUFAAY",
"ItemNumber":"0000051592",
"Name":"* 25 Comp Glass Rack - 3 Ext - Red Base"
},
{
"Id":"8028s000000kyUGAAY",
"ItemNumber":"0000051593",
"Name":"* 36 Comp Glass Rack 3 Ext - Gray"
}
]
}

Try like this:
%dw 2.0
output application/json
---
{
"Id" : payload[0].Order.Id,
"Order Name": payload[0].Order.Account_Name__c,
"Line Items" : payload map{
Id: $.Id,
ItemNumber : $.OrderItemNumber,
"Line Items" : $.Product2.Name
}
}

Assuming that all the order IDs are same you can just map the Id directly from payload and use the map on payload to get the Line Items
%dw 2.0
output application/json
---
{
Id: payload[0].Order.Id,
"Order Name": payload[0].Order.Account_Name__c,
"Line Items": payload map {
Id: $.Id,
ItemNumber: $.OrderItemNumber,
Name: $.Product2.Name
}
}

Here is one more option that you can try when ordered Id's are not the same
%dw 2.0
output application/json
---
payload groupBy ((item, index) -> item.Order.Id)
mapObject ((value, key, index) ->
{"Id": value.Order.Id[0],
"Order Name": value.Order.Account_Name__c[0],
"Line Items": value map ({
Id: $.Id,
ItemNumber: $.OrderItemNumber,
Name: $.Product2.Name
})}
)

Related

MuleSoft DataWeave to roll up joined query results

I have returned some data from a database call which joins several tables together. The current payload looks something like this:
[
{ "ID": 11111
, "Ref": "123ABC"
, "Year": 1994
, "Title": "A title"
, "Author": "Joe Bloggs"
},
{ "ID": 11111
, "Ref": "123ABC"
, "Year": 1994
, "Title": "A title"
, "Author": "John Smith"
},
{ "ID": 22222
, "Ref": "456DEF"
, "Year": 2018
, "Title": "Another title"
, "Author": "Lucy Jones"
}
]
Can anyone help with the DataWeave required to translate it to this:
[
{ "ID": 11111
, "Ref": "123ABC"
, "Year": 1994
, "Title": "A title"
, "Authors": [ {"Name": "Joe Bloggs"}, {"Name": "John Smith"} ]
},
{ "ID": 22222
, "Ref": "456DEF"
, "Year": 2018
, "Title": "Another title"
, "Authors": [ {"Name": "Lucy Jones"} ]
}
]
I've tried playing around with distinctBy and filter, but have only managed to get this so far:
%dw 2.0
output application/json
var myVar = payload distinctBy () ->
{ ID: $.ID
, Ref: $.Ref
, Year: $.Year
, Title: $.Title
}
---
myVar map () -> using (thisID = myVar.ID)
{ ID: $.ID
, Ref: $.Ref
, Year: $.Year
, Title: $.Title
, Authors: payload map {Name: $.Author}
//, Authors: payload filter ($.*ID contains thisID) map {Name: $.Author}
}
Result:
[
{
"ID": 11111,
"Ref": "123ABC",
"Year": 1994,
"Title": "A title",
"Authors": [
{
"Name": "Joe Bloggs"
},
{
"Name": "John Smith"
},
{
"Name": "Lucy Jones"
}
]
},
{
"ID": 22222,
"Ref": "456DEF",
"Year": 2018,
"Title": "Another title",
"Authors": [
{
"Name": "Joe Bloggs"
},
{
"Name": "John Smith"
},
{
"Name": "Lucy Jones"
}
]
}
]
Assuming fields other than the Author will be same for a particular ID, you can use groupBy to make groups for each ID.
Then map the grouped values by updating the Author to be equal to the combined value of all the Author in the group.
%dw 2.0
output application/json
---
payload groupBy $.ID
pluck ((groupedValues) -> {
(groupedValues[0] - "Author"),
Author: groupedValues map {Name: $.Author}
})
Also note that using keyword is deprecated in Mule 4, so avoid using it. You should instead use the do block for it

Swagger API having different response with the change of Optional Parameters

I am trying to create the OAS Swagger documentation for an existing API where the response for the API is changing on the basis of Query parameter. I am struggling to document this in a developer friendly way, so need some assistance. Below is the complete scenario for your reference.
EndPoint 1 : /order?expand=false
/order?expand=false
{
"orderNo": "12345",
"orderDetail": "Description of Order",
"orderMarket": {
"id": "UK"
},
"brandOrderStatus": {
"id": "LLA"
}
}
Endpoint 2 : /order?expand=true
{
"orderNo": "12345",
"orderDetail": "Description of Order",
"orderMarket": {
"id": "UK",
"descr": "United Kingdom",
"lang": "en-GB"
},
"brandOrderStatus": {
"id": "LLA",
"descr": "Some Status Description",
"lang": "en-GB"
}
}
Endpoint 3 : /order?expand=true&include=feature
{
"orderNo": "12345",
"orderDetail": "Description of Order",
"orderMarket": {
"id": "UK",
"descr": "United Kingdom",
"lang": "en-GB"
},
"brandOrderStatus": {
"id": "LLA",
"descr": "Some Status Description",
"lang": "en-GB"
}
"_embedded": {
"features": [
{
"id": "AJS",
"type": "FeatureType",
"descr": "FeatureDescription",
"prices": [
{
"type": "msrpNetPrice",
"amount": 0.00,
"currency": "GBP"
}
],
"group": "null"
}
]
}
}
I tried using OneOf, but don't really think that will work in this case as the structure is changing with every optional parameter.
Any thoughts as how this can be documented in Swagger documentation ? Or any other idea to get this documented.

Nested array data transformation with Mule 3

I am trying to transform data in Mule 3 (DataWeave 1.0) but I am not getting the desire result.
This is the input payload:
[
"https://scrum-caller.com/repo/v1/inside#Changes",
[
{
"id": "8db55441-6255-4d24-8d39-658536985214",
"number": "0w-30",
"Desc": "maintain"
}
],
"https://scrum-caller.com/repo/v1/inside#Changes",
[
{
"id": "11111111-6666-2222-3g3g-854712547412",
"number": "5w-40",
"Desc": "on prod"
}
],
"https://scrum-caller.com/repo/v1/inside#Changes",
[
{
"id": "1ab32c5b-ffs3-3243-74fv-3376218042bb",
"number": "5w-30",
"Desc": "on test"
}
]
]
And my desire output need to be like the one below
{
"#odata.context": "https://scrum-caller.com/repo/v1/inside#Changes",
"value": [
{
"id": "8db55441-6255-4d24-8d39-658536985214",
"number": "0w-30",
"Desc": "maintain"
},
{
"id": "11111111-6666-2222-3g3g-854712547412",
"number": "5w-40",
"Desc": "on prod"
},
{
"id": "1ab32c5b-ffs3-3243-74fv-3376218042bb",
"number": "5w-30",
"Desc": "on test"
}
]
}
Thanks for helping guys.
Assuming all the URLs are the same, since the question doesn't provide details only an example, I just take the first element as the value of the input for "#odata.context", the the value is just filtering out the non-array elements and use the reduce operator to get a single array of the other elements.
%dw 1.0
%output application/json
---
{
"#odata.context" : payload[0],
value : payload filter ($ is :array) reduce ($ ++ $$)
}

Dynamic object key to display *ngFor in Nativescript with Angular

I have the dataset which has derived from the group by product name as below. I need to iterate the array of object and display the product name with all the size of the product.
Sample dataset
[ {
"TEST 1": [
{
"content_id": "88282",
"product_name": "TEST 1",
"price": "36.00",
"size" : "XL"
},
{
"content_id": "88283",
"product_name": "TEST 1",
"price": "37.00",
"size" : "XXL"
}
}],
{
"TEST 2": [
{
"content_id": "882821",
"product_name": "TEST 2",
"price": "36.00",
"size" : "XL"
},
{
"content_id": "882832",
"product_name": "TEST 2",
"price": "37.00",
"size" : "XXL"
}]
]
I need to iterate the above result and need to display as Product name with all sizes such as "TEST 1 (XL XXL ) and TEST 2 (XL XXL)
What I am trying is
<----- need to display here --------->
You can use Object.keys() to get keys or use foreach() to iterate json.
E.g.
const object1 = {"data":
[ { "TEST 1": [ {
"content_id": "88282",
"product_name": "TEST 1",
"price": "36.00",
"size" : "XL"
}, {
"content_id": "88283",
"product_name": "TEST 1",
"price": "37.00",
"size" : "XXL"
}
]
}
]
};
object1[Object.keys(object1)[0]].forEach(function(element) {
console.log(element);
});

How to invert the MQL query (for freebase)?

I am trying to list all the types for a particular id:
{
"id": "/en/sony",
"type": [{
"name": "Topic",
"id": null
}]
}
This query giving me the following result:
http://tinyurl.com/lubavey
{
"result": {
"type": [
{
"id": "/common/topic",
"name": "Topic"
},
{
"id": "/base/audiobase/topic",
"name": "Topic"
},
{
"id": "/base/fblinux/topic",
"name": "Topic"
},
{
"id": "/base/digitalcameras/topic",
"name": "Topic"
},
{
"id": "/base/popstra/topic",
"name": "Topic"
},
{
"id": "/base/televisions/topic",
"name": "Topic"
},
{
"id": "/base/ps3games/topic",
"name": "Topic"
},
{
"id": "/base/filmcameras/topic",
"name": "Topic"
},
{
"id": "/m/04mny2g",
"name": "Topic"
}
],
"id": "/en/sony"
}
}
I want exactly the opposite result. I want all the types which do not have name as "Topic" with them.
How can I achieve this? I tried to use ! operator with property name which is suggested in reference guide of MQL, but it's giving me error:
"Can't use unqualified property names with ! reversing".
What should I do to remove this error with ! and to obtain opposite result of the query?
Try with !=:
{
"id": "/en/sony",
"type": [{
"name!=": "Topic",
"id": null
}]
}
The != operator says that the constrained property can be anything but
the specified value. (It does require that the property be something,
however: it does not match object for which the property is null.)
Read more about != operator here: http://wiki.freebase.com/wiki/MQL_operators#The_.22but_not.22_Operator_.21.3D