POST a JSON list [] using 'Choose from List' (Select Multiple on) in Shortcuts

4.4k Views Asked by At

Here is an example of a JSON array Shortcut to test JSON lists (with a working API token in a test environment).

There are a handful of 'Quick Look' and Pretty Print Dictionary actions through the Shortcut for ease of readability.

The ideal model

Using a 'Choose from List' action, Shortcut users select from a list of displayed tags for a project. Users can select multiple tags from the list (Select Multiple is enabled). Shortcuts then performs the 'Get contents of URL' action to send a POST request with a JSON 'Request Body'. The three main keys are: pid (project ID) as a number, created_with as a string, and tags as an array:

"data": {
    "pid": 123,
    "created_with": "Workflow",
    "tags": [ "bar1", "bar2", "bar3" ]
}

Sending 'Chosen Items' array

If I send tags with the value from the Chosen Item (an array of items selected from the 'Choose from List' action) to the 'Get contents of' action, Shortcuts interprets that list. Instead of passing the list as an array of strings (as listed in the ideal example above), it is passed as a single string with list items separated by \n new lines:

"tags": [ "bar1\nbar2\nbar3" ]

Note: the Shortcut example uses a 'Get contents of' action to return all tags (including new tags created from sending back these long strings), so the selection of tags has been hardcoded for ease of use.

If a user selects and sends a single tag (e.g. bar2), there is no extra mangling (as there are no extra new lines added), and the array is built as expected (e.g. "tags": [ "bar2" ]).

Send 'Combine Text' "built" array

Trying to circumvent this, I have tried a combination of the 'Combine' and 'Text' actions to make my own array.

Combine 'Chosen Item' with 'Custom' ","

Text
"Combined Text"

Set variable 'tags' to "Text"

If I do that, Shortcuts gets 'escape happy', with the result of selecting three tags as follows:

"tags": [ "\"bar1\",\"bar2\",\"bar3\"" ]

Down the path of 'escaping double quotes' lies madness (\\\",\\\") and changing the double quotes to single quotes sends the resulting array as a string:

"tags": [ "'bar1','bar2','bar3'" ]

This leads me to look at the 'Request Body' of the 'Get contents of' action, as the double quotes are added in before an array. The 'Get contents of' action has tags as an array.

If you dive into the tags array item (in the 'Get contents of' action), the choices I can add are text, number, array, dictionary, or boolean. Choosing array will make an array in this array (not what I want, it already is an array), so text is the best option. This is where I have singled out the double quotes are coming from. Knowledge is power.

Get Dictionary from Input

I have also tried to use 'Get Dictionary from Input' action to convert the array to a dictionary, parse that as a variable, then drop that into the 'Get contents of' action request. The only way I can see this working is if I convert and build all of my Request Body through a 'Get Dictionary from Input' action, as the request body is already of type 'dictionary' – adding a text item to a dictionary adds a key-value pair for text (I can't drop a dictionary or an array in).

List individual tags in 'Get content of' action

The only other workaround I can think of is to have a 'For Each' action save each selected tag as a separate variable, and pass each tag into the final array item of tags.

Adding each to a separate variable to list as text under the tags array seems cumbersome and brittle. If 'dynamic variables' were possible, ChosenTag_n could be used in place, where n is the index of the selected tag. For now, an example is hardcoded in a biiiig nested 'If' action (oh no).

On the bright side, this does work:

"tags": [ "bar1", "bar2", "bar3" ]

... however, it will "lose data" if 'Chosen Items' > number of ChosenTag_n variables. I've also just created my own array in singular variables, and nested 'If' statements. Double sigh.

Possible solutions and TL;DR

Ideally, the (multiple) items selected from the 'Choose from List' action should be formatted as an array, and the 'Get contents of' action should accept and parse the array as expected.

I am trying to avoid creating or writing to a file, as well as avoid creating my own custom 'Request Body'.

I have only found this one other post (Reddit) on the same topic (now archived).

Is Shortcuts not parsing arrays properly/is this something iOS 14 addresses and fixes, or (more likely) did I potato and I'm missing something key in formatting arrays?

1

There are 1 best solutions below

1
On

I just spent I don't know how much time trying to figure this out (calling the Sonos API through shortcuts), and I finally found a way to do it. I'm hoping that there actually is a better answer, but I haven't found it!

The solution is to write it all to a Dictionary: Using the Dictionary action you run into the same problem (you cannot assign lists to the dictionary), but using Set Dictionary Value action you can (note that this actually copies your dictionary with the value added). You can do this with an empty source-dictionary to create a new dictionary with just this one value.

Next step is to send this dictionary; just create a Get Contents of URL with action = POST, and set the Request Body to File and provide the Dictionary you just made.

Using https://postman-echo.com/post (an api that just echos your request back to you), it seems that Shortcuts (iOS 15 at least) just sends the provided dictionary as JSON, and even adds the correct Content-Type request header.