I have a json = - mule

I have input json
[
{
"nm": "BRANCHID",
"vl": "1"
},
{
"nm": "TELLERID",
"vl": "9903"
},
{
"nm": "mobile",
"vl": "9903234565"
}
]
I need to check nm equal to BRANCHID or TELLERID then would set V1 value accordingly and output:
{"BRANCHID":"1"},
{"TELLERID",:"9903"}

Filter by the items you need and then construct a new object combining the nm and vl attributes:
%dw 2.0
output application/json
---
payload
filter ((item) -> item.nm == 'BRANCHID' or item.nm == "TELLERID")
map ((item) -> {(item.nm) : item.vl})

Sort the data into a new object. There's probably a more sophisticated way to do this, but this should work.
let newObj = {};
json.forEach(sort);
function sort(item, index){
newObj[ json[index].nm ] = json[index].vl;
}
https://jsfiddle.net/r75haec8/

Related

Lodash: filter when I have nested array property?

Consider below example. I am using Lodash
"home":[
{
"data":{
"interests":["sports", "travel", "boxing"],
"city":["x", "y", "z"],
"name":"test1"
},
"count":["1", "2"],
"country":"CA"
},
{
"data":{
"interests":["painting", "travel", "dancing"],
"city":["a", "y", "b"],
"name":"test2"
},
"count":["1","3"],
"country":"US"
}
]
If I'll try the function on key value pair example :
_.find(home, ['data.country', 'US']); // It is returning me the 2nd object
requirement :
I want all the objects where data.interests is 'dancing'.
Tried :
_.find(home, ['data.interests', 'dancing']) // It is returning []
I have also tried filter(), where() and map but unable to get the complete object.
Thanks in advance.
You can use vanilla JS or lodash funcntions - Filter the array, and for each item check if the data.interests array includes the requested word.
Vanilla:
const home = [{"data":{"interests":["sports","travel","boxing"],"city":["x","y","z"],"name":"test1"},"count":["1","2"],"country":"CA"},{"data":{"interests":["painting","travel","dancing"],"city":["a","y","b"],"name":"test2"},"count":["1","3"],"country":"US"}]
const result = home.filter(o => o.data.interests.includes('dancing'))
console.log(result)
Lodash:
const home = [{"data":{"interests":["sports","travel","boxing"],"city":["x","y","z"],"name":"test1"},"count":["1","2"],"country":"CA"},{"data":{"interests":["painting","travel","dancing"],"city":["a","y","b"],"name":"test2"},"count":["1","3"],"country":"US"}]
const result = _.filter(home, o => _.includes(o.data.interests, 'dancing'))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Inline transform specific attributes in JSON payload containing nested arrays and objects of key/value pairs

I have an input payload that I need to pass through directly to the output except for specific date attributes which I need to transform. These date attributes can be anywhere within the payload. i.e.,
as key/value pairs
as key/value pairs within an object
as key/value pairs within an array
as key/value pairs within an object in an array
I have addressed cases 1 and 2 above with the dataweave code below. However, I am a little stuck with cases 3 and 4. Would very much appreciate any pointers in this regard. Thanks!
Input payload:
{
"key1":"value1",
"key2":"value2",
"arrayList1":[
{
"key3":"value3",
"datefield_1":"13/01/2006",
"datefield_2":"15/06/1980",
"arrayList2":[
{
"key4":"value4",
"datefield_3":"13/01/2000",
"datefield_4":"15/06/2003",
"arrayList2":[
{
"key5":"value5",
"datefield_5":"30/01/2000",
"datefield_6":"14/06/2003"
}
]
}
]
},
{
"key6":"value6",
"datefield_7":"20/02/2000"
}
]
}
Dataweave code:
%dw 1.0
%output application/json
%var keysToUpdate = ['datefield_1', 'datefield_2', 'datefield_3', 'datefield_4', 'datefield_5', 'datefield_6', 'datefield_7']
%function transformDateFormat(inputDate) inputDate as :date {format: "dd/MM/yyyy"} as :date {format: "yyyy-MM-dd"}
%function findKey(key) keysToUpdate contains key
%function changePayload(input) input mapObject ({
($$): changePayload($) when $ is :object otherwise $
} unless findKey($$ as :string) otherwise {
($$): transformDateFormat($)
})
---
changePayload (payload)
The match operator with some recursion will be helpful here.
Try this out. I created a function, applyToValuesWhenKey, that takes in the input value as e, a function to apply to the values as fn, and a function that returns a boolean that will dictate whether or not to apply fn to the value called predicate. It uses recursion and the match operator to loop through the data, applying map, mapObject, or just returning the given value depending on whether or not the current value is an object, array, or anything else. The rest is your code:
%dw 1.0
%output application/json
%var input = {
"key1":"value1",
"key2":"value2",
"arrayList1":[
{
"key3":"value3",
"datefield_1":"13/01/2006",
"datefield_2":"15/06/1980",
"arrayList2":[
{
"key4":"value4",
"datefield_3":"13/01/2000",
"datefield_4":"15/06/2003",
"arrayList2":[
{
"key5":"value5",
"datefield_5":"30/01/2000",
"datefield_6":"14/06/2003"
}
]
}
]
},
{
"key6":"value6",
"datefield_7":"20/02/2000"
}
]
}
%var keysToUpdate = [ 'datefield_1', 'datefield_2', 'datefield_3', 'datefield_4', 'datefield_5', 'datefield_6', 'datefield_7' ]
%function applyToValuesWhenKey( e, fn, predicate )
e match {
:array -> $ map applyToValuesWhenKey( $, fn, predicate ),
:object -> $ mapObject ( ( v, k ) -> {
( k ): fn( v )
} when predicate( k ) otherwise {
( k ): applyToValuesWhenKey( v, fn, predicate )
}
),
default -> $
}
%function transformDateFormat( date )
date as :date { format: "dd/MM/yyyy" } as :date { format: "yyyy-MM-dd" }
%function transformDates( input )
applyToValuesWhenKey( input,
transformDateFormat,
( ( key ) -> keysToUpdate contains ( key as :string ) ) )
---
transformDates( input )

loop inside transform in mule

i am new to mule and i have to convert json to xml.here is the transform output code
%dw 1.0
%input payload application/json
%output application/xml
---
{(
items:
{
Id:payload.abc.productid,
ProductPrice:payload.abc.price,
Name:payload.abc.productname
}
)}
Here is the schema against which i am testing
{
"abc":
{
"productid":"4",
"productname":"Shampoo",
"price":["1000","2000","3000"]
}
}
It generates correct xml in case i send only one item in array price but in case i send multiple elements it gives me this error
Cannot coerce a :array to a :object.
I know i should loop inside it but i do not know how to make it possible
Please guide!
You could use the following:
{
items: {
(payload map ((payload01 , indexOfPayload01) -> {
item: {
Id: payload01.productid,
Name: payload01.productname,
(payload01.price map ((price , indexOfPrice) -> {
price: price
}))
}
}))
}
}
I have removed the "abc" from the incoming data so the format is as:
[
{
"productid":"4",
"productname":"Shampoo",
"price":["1000","2000","3000"]
},
{
"productid":"4",
"productname":"not shampoo",
"price":["1000","2000","3000"]
}
]
Let me know if the abc needs to be there, but I hope this helps
you can use the map keyword to iterate over arrays in Dataweave. Take a look at the documentation here.

Filter data using lodash

How can filter the data with some inner attribute value.
updated_id='1234';
var result= _.map(self.list, function (item) {
// return only item.User_Info.id=updated_id
});
You can use the lodash#matchesProperty variant of lodash#filter to filter out objects that you need using the path of the property. The variant is in the 3rd example of the lodash#filter documentation.
var result = _.filter(self.list, ['User_Info.id', updated_id]);
var self = {
list: [
{ User_Info: { id: '4321' } },
{ User_Info: { id: '4321' } },
{ User_Info: { id: '1234' } },
{ User_Info: { id: '3214' } },
{ User_Info: { id: '2143' } }
]
};
var updated_id = '1234';
var result = _.filter(self.list, ['User_Info.id', updated_id]);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
lodash has a filter method:
const updated_id='1234';
const result= _.filter(self.list, item => item.User_Info.id === updated_id);
Use lodash _.filter method:
_.filter(collection, [predicate=_.identity])
Iterates over elements of collection, returning an array of all elements predicate returns truthy for. The predicate is invoked with three arguments: (value, index|key, collection).
with predicate as custom function
_.filter(myArr, function(o) {
return o.name == 'john';
});
with predicate as part of filtered object (the _.matches iteratee shorthand)
_.filter(myArr, {name: 'john'});
with predicate as [key, value] array (the _.matchesProperty iteratee shorthand.)
_.filter(myArr, ['name', 'John']);

Ramda `evolve` nested object

I have a list similar to this:
var list = [
{
stack: [
{
file: 'abc'
}
]
},
{
stack: [
{
file: 'abc'
},
{
file: 'abc'
}
]
}
];
I want to change every file name with e.g 'def'. How to do that by using ramda ?
I tried things like:
var trans = {
file: replace('abc', 'def')
};
var f = R.evolve(trans)
var f2 = R.map(f)
R.map(f2, list)
But it doesn't work. I need to include stack field in solution somehow.
Well, it's not pretty, but I think this will do it:
R.map(R.over(
R.lensProp('stack'),
R.map(R.over(R.lensProp('file'), R.replace('abc', 'def')))
))(list)
You could probably also use an evolve inside, but lenses are pretty powerful, and more generally useful.