I have a state machine with a single map state that iterate across an array of 2 elements whose output is this:
[
{
"BillingDetails": {
"BilledDurationInMilliseconds": 100,
"BilledMemoryUsedInMB": 64
},
"ExecutionArn": "arn:aws:states:us-west-2:693935722839:express:restaurantdbread:53054495-6e74-47bb-b58e-ad1f40b8282e:255e2717-5126-422a-81e4-b13e505a2f16",
"Input": "{\"restaurant_name\":\"outback\"}",
"InputDetails": {
"Included": true
},
"Name": "53054495-6e74-47bb-b58e-ad1f40b8282e",
"Output": "\"27\"",
"OutputDetails": {
"Included": true
},
"StartDate": "2022-11-17T08:47:30.364Z",
"StateMachineArn": "arn:aws:states:us-west-2:693935722839:stateMachine:restaurantdbread",
"Status": "SUCCEEDED",
"StopDate": "2022-11-17T08:47:30.435Z"
},
{
"BillingDetails": {
"BilledDurationInMilliseconds": 100,
"BilledMemoryUsedInMB": 64
},
"ExecutionArn": "arn:aws:states:us-west-2:693935722839:express:restaurantdbread:7d1597ea-973a-41ac-bf16-f506dd745566:f72ecfc1-93fc-47aa-a494-e925f9c95214",
"Input": "{\"restaurant_name\":\"ihop\"}",
"InputDetails": {
"Included": true
},
"Name": "7d1597ea-973a-41ac-bf16-f506dd745566",
"Output": "\"0\"",
"OutputDetails": {
"Included": true
},
"StartDate": "2022-11-17T08:47:30.366Z",
"StateMachineArn": "arn:aws:states:us-west-2:693935722839:stateMachine:restaurantdbread",
"Status": "SUCCEEDED",
"StopDate": "2022-11-17T08:47:30.437Z"
}
]
I need to compose an output that looks like:
[{"name": "outback", "value": 27}, {"name": "chipotle", "value": 0}]
I am adding to my state machine the following ResultSelector
:
"ResultSelector": {
"name.$": "States.StringToJson($.Input)",
"value.$": "States.StringToJson($.Output)"
},
Now I am getting something that is close to what I need:
[
{
"name": {
"restaurant_name": "outback"
},
"value": "27"
},
{
"name": {
"restaurant_name": "ihop"
},
"value": "0"
}
]
I am struggling to tune the output so that the "restaurant_name": get discarded to achieve the desired format.
I tried to tweak the ResultSelector
to use:
"ResultSelector": {
"name.$": "States.StringToJson($.Input.restaurant_name)",
"value.$": "States.StringToJson($.Output)"
},
But the workflow spits this error:
The function 'States.StringToJson($.Input.restaurant_name)' had the following error: The JsonPath argument for the field '$.Input.restaurant_name' could not be found in the input '{"BillingDetails":{"BilledDurationInMilliseconds":100,"BilledMemoryUsedInMB":64},"ExecutionArn":"arn:aws:states:us-west-2:693935722839:express:restaurantdbread:b8e9de51-1806-47ab-b4e6-1c60d6cd9fc1:9ce2cb9d-0b57-4066-b7de-a41668d6113f","Input":"{\"restaurant_name\":\"ihop\"}","InputDetails":{"Included":true},"Name":"b8e9de51-1806-47ab-b4e6-1c60d6cd9fc1","Output":"\"0\"","OutputDetails":{"Included":true},"StartDate":"2022-11-17T08:58:44.627Z","StateMachineArn":"arn:aws:states:us-west-2:693935722839:stateMachine:restaurantdbread","Status":"SUCCEEDED","StopDate":"2022-11-17T08:58:44.686Z"}'
Any suggestion on what syntax to use to only extract the name of the restaurant?
I was able to solve (or workaround) my problem by adding a new map
state which decomposes the array in input and apply a Parameters
to the Pass
task. This is what the additional state looks like:
"Map formatting": {
"Type": "Map",
"End": true,
"Iterator": {
"StartAt": "Pass",
"States": {
"Pass": {
"Type": "Pass",
"End": true,
"Parameters": {
"name.$": "$.name.restaurant_name",
"value.$": "$.value"
}
}
}
}
}
This may not be the most efficient way to achieve what I need (I may not need two separate maps to construct the output required) but right now I am focused more on the basic functionality to work than on an optimized workflow so it works for me.