Power Automate / Arrays / Get items

Power Automate: convert an array to a string with Select and Join

Turn several records into one readable summary without losing items or sending one email per row. First, check whether the flow returned a value, an object or an array.

These examples use made-up data, not client results. We checked them against Microsoft documentation but have not run them in a Microsoft environment. Try them with approved sample data before changing a live app or flow.

01 / Practical guide

Choose the output you actually need

If a flow adds an unexpected Apply to each, the value you selected is probably a collection of items. Removing the loop without checking those items can lose records. First, open the action's output in run history and check it with approved sample data.

Similar-looking operations solve different problems
You needUseWatch for
One readable line from several valuesSelect the needed property, then JoinJoin preserves repeated values.
The full array as JSON textstring(yourArray)This keeps the array structure as JSON text rather than making a readable list.
One SharePoint item with a known IDGet itemGet items returns a collection even when its filter finds one row.
A file to exchange with another systemCreate CSV table or a format that system expectsIf a title contains the separator, it can be hard to tell where one title ends.

The Microsoft data operations guide describes Select, Join and table actions. The SharePoint connector reference distinguishes Get item from Get items.

02 / Practical guide

Turn two work items into one readable line

Build a manually triggered test flow with the invented work items below. It needs no SharePoint connection or email action. Add a Compose action and rename it SampleRows. In its expression editor, enter:

json('[ {"WorkTitle":"Beacon kickoff"}, {"WorkTitle":"Harbor review"} ]')

The json(...) expression creates an array. Pasting the same characters as ordinary text can give you a string instead. Add a Data Operation Select, rename it Select_titles, and set From to this expression:

outputs('SampleRows')

Switch the Select Map to text mode, rather than entering a key/value mapping. Enter this expression as the map value:

item()?['WorkTitle']

Select should now return an array of strings, not an array of objects. Microsoft also documents this text-mode pattern in its Logic Apps Select examples. Check the output before going on:

["Beacon kickoff","Harbor review"]

Add a Join action. Set From to body('Select_titles') using the expression editor, and Join with to ; (a semicolon followed by a space). Alternatively, add a Compose containing:

join(body('Select_titles'), '; ')

The expected text is Beacon kickoff; Harbor review. If you see braces and property names, check whether Select is still making objects. If Join rejects the input, inspect its type instead of wrapping everything in string(). The expression reference covers json, item, join and string for Power Automate and Logic Apps.

Expression examples assume these exact action names. Use your flow's actual internal names if they differ. Enter formulas in the expression editor without wrapping the whole formula in quotation marks or @{...}.

03 / Practical guide

Apply the pattern to Get items

For an action actually named Get_items, the rows commonly come from body('Get_items')?['value']. Confirm that shape in its output, then use that array as Select's From. Map the real internal field name, such as item()?['Title'] for the standard SharePoint Title field. Choice, lookup and person fields need their own verified shapes.

For one combined summary, place Select and Join after the action that gets the rows, outside any loop. If you later add a single email action, put it after Join too. An email action inside Apply to each still sends once for each item.

Join cannot recover rows the query did not return. Check the filter, pagination and row limits before treating the text as a complete report. If the flow only gets part of the data, say so in the output. Keep the failure and recovery path separate from this formatting step.

04 / Practical guide

Need exactly one result? Check zero, one and many

first(...) selects the first value; it does not prove the query found only one match. If an ID or other key should match exactly one item, use the array length to choose what happens next:

length(body('Get_items')?['value'])
  • Zero: handle the missing result. Do not try to read the first record.
  • One: only in this branch, use first(body('Get_items')?['value'])?['Title'], adapting the field name.
  • More than one: stop or ask someone to review the matches. Do not silently choose a record.

A Top Count of 1 hides additional matches. To spot multiple matches, the query must be able to return at least two matching records. You may also need a rule in the data source that prevents duplicate key values. Check that the query returned all the rows it should. If you already know the item ID, use Get item and handle missing items or permission errors.

05 / Practical guide

Another example: join a plain string array

If the source already returns strings, you do not need Select. Add a Compose in a manual test flow and enter this expression:

join(json('["Beacon","Harbor","Beacon"]'), ', ')

Expected: Beacon, Harbor, Beacon. The second Beacon stays in the result because Join formats values; it does not remove duplicates. Try json('[]') as the first argument: the expected result is an empty string. With json('["Beacon"]'), the expected result is Beacon with no separator.

Use this pattern for a display string. If another system needs to rebuild the original array, send JSON or the format that system requires instead. A value containing the delimiter cannot reliably be split back using that delimiter alone.

06 / Practical guide

Another example: show a placeholder for blank titles

Sometimes a report must retain every work item, including ones with missing names. Add a Compose named SampleRowsWithBlanks, using this expression:

json('[ {"WorkTitle":" Beacon "}, {"WorkTitle":null}, {"WorkTitle":""} ]')

Add a Select named Select_display_titles. Set From to outputs('SampleRowsWithBlanks'). In Map text mode, use:

if(
  empty(trim(coalesce(item()?['WorkTitle'], ''))),
  '(untitled)',
  trim(item()?['WorkTitle'])
)

Then add a Compose containing:

join(body('Select_display_titles'), '; ')

Expected: Beacon; (untitled); (untitled). Select retains three entries. Leading/trailing spaces are removed for display; this does not update source records. This example assumes each WorkTitle is text, null or missing. If the source can send a number or object, check its type against the schema before treating it as text.

coalesce handles null or missing values here, while empty after trim also catches empty or whitespace-only text. Changing the input to {} should produce the placeholder; {"WorkTitle":" "} should too. See the expression reference and the JSON type and null guide for the distinction. These are the outputs you should check for. We have not run this flow.

07 / Practical guide

Check the inputs before adding a real action

Use Compose to check the final result. These are tests for you to run; we have not observed their results in a flow.

Small inputs reveal common mistakes
InputCheck
Empty array []The joined result is an empty string. Decide whether the summary should display a no-items message.
One objectOne title, with no extra delimiter.
The two sample objectsBeacon kickoff; Harbor review, in that order.
The same title twiceBoth appear. Decide whether repeated values should stay or be removed.
Missing or null WorkTitleChoose whether to fail, omit the row or display a placeholder before Join. Record how many rows were left out.
A title containing a semicolonThe text is readable but cannot safely be split back into the original values using that delimiter.

For missing values, a Filter array step can remove unwanted rows before Select if that is the agreed rule; unlike Select, it can reduce the number of rows. Do not quietly drop incomplete work items from a management report. Write down the agreed rule and also test values that contain only spaces.

Technical sources checked September 25, 2026. We checked this made-up example against the documentation but have not run it in a Microsoft environment.

Get help with your workflow

Need help with your team's version of this?

Tell me what you are trying to do, what is going wrong and who it affects. In a free 20-minute call, we can decide whether a workflow review or app project would help.

felipe@getquintera.com · These guides are free. We agree the work and cost of consulting separately.