Trying to use JSONata $map for Nested arrays, getting Invalid JSONata expression: Expected "{", got "["

This is barking in my change node using JSONata:

[
   $map(
       payload,
       function($v) 
       [
            {
               "fieldKey": "fieldUUID",
               "value": $v.fieldUUID
            },
            {
               "fieldKey": "fieldName",
               "value": $v.fieldName
            }
       ]
    )
]

with this error:

Invalid JSONata expression:
  Expected "{", got "["

And so is this:

[
   $map(
       payload,
       function($v) 
       {
            {
               "fieldKey": "fieldUUID",
               "value": $v.fieldUUID
            },
            {
               "fieldKey": "fieldName",
               "value": $v.fieldName
            }
        }
    )
]

with this error:

Invalid JSONata expression:
  Expected "}", got ","

Both are perfectly valid JSON after the function().

The target API endpoint request body requires the following:

        {
            "fieldKey": "Fields",
            "value": [
                [
                    {
                        "fieldKey": "fieldUUID",
                        "value": "8be8e0ff-b7c8-4762-8d2d-36a176d55923"
                    },
                    {
                        "fieldKey": "fieldName",
                        "value": "Big Muddy"
                    }
                ],
                [
                    {
                        "fieldKey": "fieldUUID",
                        "value": "aaba874a-8629-4c8b-a410-b1b3bc35c6e8"
                    },
                    {
                        "fieldKey": "fieldName",
                        "value": "Grandma's"
                    }
                ],
                [
                    {
                        "fieldKey": "fieldUUID",
                        "value": "ab17ddc4-7726-438b-9bb1-95112a089f02"
                    },
                    {
                        "fieldKey": "fieldName",
                        "value": "Jefftown Creek"
                    }
                ]
            ]
        }
    

GeoJSON coordinates and a lot of other standard APIs have nested array requirements as well.

                    "geometry": {"type":"Polygon","coordinates":[[[-73.98779153823898,40.718233223261],[-74.004946447098,40.723575517498],[-74.006771211624,40.730592217474],[-73.99010896682698,40.746712376146],    [-73.973135948181,40.73974615047701],[-73.975120782852,40.736128627654],[-73.973997695541,40.730787341083],[-73.983317613602,40.716639396436],[-73.98779153823898,40.718233223261]]]}

Hard to say with out the data you are mapping, but looks like you are missing the scope { } around the array.

[
$map(
       payload,
       function($v) {
          [ 
             {
               "fieldKey": "fieldUUID",
               "value": $v.fieldUUID
            },
            {
               "fieldKey": "fieldName",
               "value": $v.fieldName
            }
        ]
 } )
]

As long it is not expecting an object. The other test in the main ticket had a similar set of brackets {}.

Worked thanks again for the extra set of eyes.

[
   $map(
       payload,
       function($v) {
       [
            {
               "fieldKey": "fieldUUID",
               "value": $v.fieldUUID
            },
            {
               "fieldKey": "fieldName",
               "value": $v.fieldName
            }
       ]}
    )
]

When there is more than one record in my CSV I get the correct JSON

[
    [
        {
            "fieldKey": "seasonFieldUUID",
            "value": "1b3bac39-48fd-45e6-a394-9c9cbb455d6c"
        },
        {
            "fieldKey": "fieldName",
            "value": "Paddy 1"
        }
    ],
    [
        {
            "fieldKey": "seasonFieldUUID",
            "value": "f09dd5a9-0c81-4e82-b19c-0accdba0e4a6"
        },
        {
            "fieldKey": "fieldName",
            "value": "Paddy 2"
        }
    ]
]

But when there is only one record for an email in the CSV:

[
    {
        "fieldKey": "seasonFieldUUID",
        "value": "ee80aa12-00ad-4f98-81dc-9180956634b6"
    },
    {
        "fieldKey": "fieldName",
        "value": "Lower NW"
    }
]

Whereas it should be:

[
    [
        {
            "fieldKey": "seasonFieldUUID",
            "value": "ee80aa12-00ad-4f98-81dc-9180956634b6"
        },
        {
            "fieldKey": "fieldName",
            "value": "Lower NW"
        }
    ]
]

So for some reason JSONata $map is converting my array to an object instead of the nested arrays. That seems to be a bug. Certainly not a feature.

The calls to the API are bombing.

Are people putting conditional logic as a workaround? Hopefully not a switch node based on $count(array) to two separate change nodes. Not sure how to pull this off inside JSONata at the moment.

Here is the input:

[
    {
        "farmerUUID": "ed89d7a5-f0c1-49c3-8221-808ba80e3502",
        "farmerFirstName": "Steve",
        "farmerLastName": "Cropper",
        "retailerName": "HarvestStates",
        "businessDBAName": "Crops R Us",
        "farmerEmailAddress": "steve.cropper@gmail.com",
        "seasonFieldUUID": "8be8e0ff-b7c8-4762-8d2d-36a176d55923",
        "fieldName": "Big Muddy"
    },
    {
        "farmerUUID": "ed89d7a5-f0c1-49c3-8221-808ba80e3502",
        "farmerFirstName": "Steve",
        "farmerLastName": "Cropper",
        "retailerName": "HarvestStates",
        "businessDBAName": "Crops R Us",
        "farmerEmailAddress": "steve.cropper@gmail.com",
        "seasonFieldUUID": "aaba874a-8629-4c8b-a410-b1b3bc35c6e8",
        "fieldName": "Grandma's"
    },
    {
        "farmerUUID": "ed89d7a5-f0c1-49c3-8221-808ba80e3502",
        "farmerFirstName": "Steve",
        "farmerLastName": "Cropper",
        "retailerName": "HarvestStates",
        "businessDBAName": "Crops R Us",
        "farmerEmailAddress": "steve.cropper@gmail.com",
        "seasonFieldUUID": "ab17ddc4-7726-438b-9bb1-95112a089f02",
        "fieldName": "Jefftown Creek"
    },
    {
        "farmerUUID": "00e59dad-4072-4640-b5bb-7dca5521e54e",
        "farmerFirstName": "Jeffrey",
        "farmerLastName": "Paddyman",
        "retailerName": "Truterra",
        "businessDBAName": "Bogs of Rice",
        "farmerEmailAddress": "paddy@gmail.com",
        "seasonFieldUUID": "1b3bac39-48fd-45e6-a394-9c9cbb455d6c",
        "fieldName": "Paddy 1"
    },
    {
        "farmerUUID": "00e59dad-4072-4640-b5bb-7dca5521e54e",
        "farmerFirstName": "Jeffrey",
        "farmerLastName": "Paddyman",
        "retailerName": "Truterra",
        "businessDBAName": "Bogs of Rice",
        "farmerEmailAddress": "paddy@gmail.com",
        "seasonFieldUUID": "f09dd5a9-0c81-4e82-b19c-0accdba0e4a6",
        "fieldName": "Paddy 2"
    },
    {
        "farmerUUID": "0d401180-715a-4094-94b5-fc2a6ea05520",
        "farmerFirstName": "Jimmy",
        "farmerLastName": "Fields",
        "retailerName": "Truterra",
        "businessDBAName": "Fields a Crackin",
        "farmerEmailAddress": "jimmy.fields@gmail.com",
        "seasonFieldUUID": "ee80aa12-00ad-4f98-81dc-9180956634b6",
        "fieldName": "Lower NW"
    }
]

Related comment, which I don't understand why it would behave this way.

What is the reason for using map ?
By default JSONata acts like a map already, ie.

*.[
    {
        "fieldKey":"seasonFieldUUID",
        "value":$.seasonFieldUUID
    },
    {
        "fieldKey": "fieldName",
        "value": $.fieldName
    }
]

Not sure why it flattens the array when there is a single element, could be default behaviour of jsonata.
see
https://try.jsonata.org/HgCAb01Zz

if you add [] to the end of the expression, it will nest it in an array with a single element.

eg.:

*.[
    {
        "fieldKey":"seasonFieldUUID",
        "value":$.seasonFieldUUID
    },
    {
        "fieldKey": "fieldName",
        "value": $.fieldName
    }
][]

I ended up with a ternary operation to make it consistent:

$count(payload) = 1 ? 
[
   $map(
       payload,
       function($v) {
           [[
               {
                   "fieldKey": "seasonFieldUUID",
                   "value": $v.seasonFieldUUID
                            },
               {
                   "fieldKey": "fieldName",
                   "value": $v.fieldName
                            }
            ]] 
        }
    )
]
:
[
   $map(
       payload,
       function($v) {
           [
               {
                   "fieldKey": "seasonFieldUUID",
                   "value": $v.seasonFieldUUID
                            },
               {
                   "fieldKey": "fieldName",
                   "value": $v.fieldName
                            }
            ]
        }
    )
]

Ending that with is good to know.

Using the map functions should be faster than the . operator.

@dubnemo I see no reason to use the ternary operator. You can add [ ]at end or surround the whole expression with [expression] it is has the same result.

This doesn't seem to work.

Using the map functions should be faster than the . operator.

If speed is a concern, I would recommend to use javascript instead.

What doesn't seem to work, please supply example.

The updated JSONata 2 has speed performance increases the functions I have tested are compareible to Javascript.