cancel
Showing results for 
Search instead for 
Did you mean: 

Mappping element of a Subarray of a JSON document in mapper snap

MarotReply
New Contributor II

Hello, I have an issue with splitting a JSON document in a mapper.
In short, this document is received via a REST Get Snap and certain elements of it should be mapped to certain names, think for example:

Received JSON:
{
“Property1”:“value1”,
“Property2”:“value2”,
“Property3”:“value3”,
“Subarray”:[
{
“SubProperty1”:“subValue1”,
“SubProperty2”:“SubValue2”,
“SubProperty3”:“SubValue3”
},
{
“SubProperty1”:“subValue4”,
“SubProperty2”:“SubValue5”,
“SubProperty3”:“SubValue6”
}
]
}

And the produced JSON should look something like this:

{
“Prop1”:“value1”,
“Prop2”:“value2”,
“MyArray”:[
{
“SubProp1”:“subValue1”,
“SubProp2”:“SubValue2”,
},
{
“SubProp1”:“subValue4”,
“SubProp2”:“SubValue5”,
}
]
}

In and of itself, this should be a simple task, we have only to map some input values to some output values. However when mapping the values in the subarray like so:

$ SubProperty1 → $Prop1
$ SubProperty2 ->$Prop2
jsonPath($, "$SubArray[].SubProperty1") → $MyArray[].SubProp1

instead of producing the second JSON as required it produces something like this:
{
“Prop1”:“value1”,
“Prop2”:“value2”,
“MyArray”:[
{
“SubProp1”:[
“subValue1”,
“subValue4”
],
“SubProp2”:[
“SubValue2”,
“SubValue5”
]
}
]
}

So it seems that instead of splitting the values of the elements in SubArray between the elements in MyArray, it sees the array of the elements as one unit and therefore populates only the first element in MyArray with a vector containing the elements of SubArray.

I’ve been trying various things but I can’t seem to solve this, any help would be appreciated.
Note that since the data comes from a Rest Call, snaplogic doesn’t know until execution what the data should look like.

I hope that was clear, the problem itself is rather simple but the explanation is somehow a little complicated.

Thanks in advance!

1 ACCEPTED SOLUTION

you can use the match operator to match the each doc in the array and map it to whatever you’d like

so using this expression:

$Subarray.map(entry => match entry { {SubProperty1, SubProperty2} => {"SubProp1": SubProperty1, "SubProp2": SubProperty2}, _ => []})

mapped to MyArray should give you the desired output for the nested array portion. The rest seems to just be direct mappings from source Property1 to target Prop1, Property2 to target Prop2 while setting pass through to off.

One thing to note, the ‘_’ is used as a default incase there is a document that does not match any of the arms in the match. So, if there is a doc that does not have these fields it would default to an empty array, which you can change.

View solution in original post

9 REPLIES 9

MarotReply
New Contributor II

I haven’t yet found a solution, so yes.
Also here are the formatted JSONS:

Received JSON:

{
   "Property1":"value1",
   "Property2":"value2",
   "Property3":"value3",
   "Subarray":[
   {
       "SubProperty1":"subValue1",
       "SubProperty2":"SubValue2",
       "SubProperty3":"SubValue3"
   },
   {
       "SubProperty1":"subValue4",
       "SubProperty2":"SubValue5",
       "SubProperty3":"SubValue6"
   }
   ]
}

Should be Produced JSON:

{
   "Prop1":"value1",
   "Prop2":"value2",
   "MyArray":[
      {
         "SubProp1":"subValue1",
         "SubProp2":"SubValue2",
      },
      {
         "SubProp1":"subValue4",
         "SubProp2":"SubValue5",
      }
   ]
}

I have found that I can manipulate the subArrays by using a JSON splitter and working on each one individually, I have not however found out how to use the join snap to properly put them back into the required space once this is done.

you can use the match operator to match the each doc in the array and map it to whatever you’d like

so using this expression:

$Subarray.map(entry => match entry { {SubProperty1, SubProperty2} => {"SubProp1": SubProperty1, "SubProp2": SubProperty2}, _ => []})

mapped to MyArray should give you the desired output for the nested array portion. The rest seems to just be direct mappings from source Property1 to target Prop1, Property2 to target Prop2 while setting pass through to off.

One thing to note, the ‘_’ is used as a default incase there is a document that does not match any of the arms in the match. So, if there is a doc that does not have these fields it would default to an empty array, which you can change.

Thank you, this solutions seems to work!

This works, thank you very much!

ptaylor
Employee
Employee

As I explained in my first reply, this is very straightforward using two Mappers.

One Mapper to map the elements at the root level:

Screen Shot 2021-01-20 at 9.23.57 AM

And another Mapper to map the elements of the subarray, using the Mapping Root feature:

Screen Shot 2021-01-20 at 9.25.13 AM

Here’s this solution as a pipeline:

Community9229_2021_01_20.slp (5.1 KB)