Expression Interlude - Random Item from Array in Power Automate
While working on Part-Two of the Birthday Bot project, I came across something pretty cool that I wanted to share:
There is no inherent way to grab a random item from an array inside Microsoft Power Automate / Flow. There is a rand() function, but that picks a random number in a range between two numbers that you specify. But we can use that with another trick to grab a specific 'row' from within an array.
As I discovered in Birthday Bot - Part One - v2.0, when wrapped around an array, the length() function will return the number of 'rows' within that array. So, if my array has 7 items...numbered from 0 to 6, adding some version of the expression below to the end of a body() or outputs() will pick one of those items at random.
In my Birthday Bot example, I wanted to select a random birthday card from Handwrytten to submit to the user for approval, and combine that with the randomly selected text to complete a card and send it to a physical address. Using their very well-documented API, I was able to see that Birthday Cards were identified as "Category 7", so I used another HTTP call to list all of the cards in that category. There is no authentication needed for this step and will produce an output that looks like this:
By listing the cards dynamically with each Birthday Bot engagement, this process will be mostly-stable even if the folks at Handwrytten change up the cards.
The next part took quite a few iterations as I made it more and more efficient, but I ended up with something I think is pretty cool.
If I wanted all of the cards in the body, the expression would simply be:
And if I wanted only the information for the second card, I would just add a  to the end of that: body('List_Cards')?['cards'] (keeping in mind that arrays start with  for the first 'row').
So to get a random row, I would just need to replace the  with my random expression from above, which would look like rand(0, length(body('List_Cards')?['cards'])) where I ask Power Automate to pick a random number in a range that begins at zero, and goes up to (but doesn't include) the number of rows in my array. Meaning: If my array has 8 rows, then the rand() function will equate to rand(0,8) which will pick a number between 0 and 7. Weird, I know, but that's how it works.
The last piece is to grab only the "name" from the randomly selected row. My intent on the journey is to have the user approve the quote that will be on the card, and then approve the card from the name just in case the card randomizer pics a card that may not be suitable for the intended audience. To do this, I just add "?['name']" (no double quotes) to the end of the expression, so the whole thing together looks like this:
And will produce the name of the card for the user's approval before sending out.
Reiterating the value of the community, I had exceptional help on the expression from Pieter Veenstra and Elaiza Benitez, as well as Ashley Rogers who took the time to help me understand how to pull information from previous steps.
Get in, make mistakes, learn some things, and have fun! If you get into trouble, there are a bunch of smart people eager to help you succeed!