Tip #1258: Dynamic attribute names in Flow

You know who are the most relentless follow-uppers? Super Simple Flow users, that’s who.

Thank you everyone for your answers to my previous question. I have a follow up question. Is it possible to get the value of an attribute off of an entity dynamically instead of declaratively? E.g. instead of blah?[0]?.fullname something like blah?[0]?[someattributenameIgotinapreviousstep]

Michael “Super Simple Flow User” Ochs

Demo

Let’s consider a scenario where you need to build a full name of a contact while taking into account that some countries do not follow ‘firstname lastname’ convention. For example, to a Westerner, Chinese names are rather complicated. In a real-life implementation I would consider keeping fullname as a separate custom field, just to be on a safe side. But for the demo sake, let’s say we would like to follow ‘lastname firstname’ convention if contact’s account is located in China.

Side note: this Flow also demonstrates a scenario when variables do make sense.

The full flow may look like this:

Let’s break it down.

  • First step is given to us by On Record Selected trigger (on account entity)
  • Second step is getting the last created contact. See Tip #1256.
  • Next two steps simply declare the variables to hold the field names for the first and last names (as they come from CDS)
  • Shall we swap? is a cute name when we check the parent account’s country and swap the attribute names
  • Finally, we’re ready to build the full name. Expression we built in Tip #1257 just got a bit more complicated (I broke it down to separate lines for the readability):
concat(
  body('Get_Last_Contact')?['value']?[0]
    ?[variables('FirstName')],
  ' ',
  body('Get_Last_Contact')?['value']?[0]
    ?[variables('LastName')]
)
  • The last step is unchanged from Tip #1257 – we send ourself a mobile notification with the fullname we just built

The end result (after relocating Alpine Ski House to China):

A mobile notifcation displaying last name then first name for a contact

Time for Doubinski George to take a small break from Flow.

Cover photo by unsplash-logoAndersen Jensen

Tip #1257: Learn Compose action in Flow

I wanted to name this tip “Do not use variables in Flow” but then it would have been a click-bait, not a tip.

Yesterday we worked our way through the concept of getting an attribute of the first record from the list. The very first step we avoided was to “declare the variable”. Yes, it would have worked but unless we intend to modify the value, it’d be a one-off assignment.

If you need a result of an expression and you are not planning to modify the value then, instead of a variable, consider using Compose action (which takes its name from the intent of taking multiple inputs and building a single output).

Using the same example (getting the full name of the last created contact for an account):

Expression in the Last Contact’s FullName Compose action is (note the use of ? to avoid runtime errors):

body('Get_Last_Contact')?['value']?[0]?.fullname

Expression in the results check is:

empty(outputs('Last_Contact''s_FullName'))

Advantages of using Compose:

  • No overhead of creating and maintaining the variable
  • Can be used in a scope (variables can only be declared at the top level)
  • Simples!

The only downside I can think of (besides of using – gulp – code!) is that the only visual property available is Output which could potentially make the downstream use unclear.

Cover photo by unsplash-logoIsaac Ibbott

Tip #1256: Get attribute of the first record from the list

This is probably a super simple question, but I’m a super simple flow user. After listing records from D365 how would I go about retrieving an attribute value of the first result returned?

Michael “Super Simple Flow User” Ochs

I won’t name the person who suggested the following:

  1. Declare variables to store values.
  2. Include top 1 limit for your query.
  3. Loop through your set (so 0 or 1 record) and set required values to variables.
  4. Use it and enjoy.

You know who you are, Andrii “Granny’s Moonshine” Butenko, and credit is where credit due – step 2 is actually correct if you only need that one record. I guess step 4 is also correct when you get something right.

The way I would do it:

  1. Build the query using filter, orderby and top to get exactly what I am after.
  2. Use expression to get the attribute while avoiding the runtime errors.

Demo

Let’s say I have an account and I want to find the full name of child contact created last.

Build the query by filtering contacts on the parent account, ordering the results by createdon in descending order (so that the last created contact is on top), then limiting results to 1.


After that, use the following expression to get the full name of the first contact returned.

body('Get_Last_Contact')?['value']?[0]?.fullname

Note that the query may or may not return any results so we use question mark operator (?) to avoid runtime errors.

To reference null properties in an object without a runtime error, use the question mark operator.

Workflow Definition Language schema

The result is either the full name or empty (if account has no contacts).

The only downside of using the expression (besides being not-exactly-nocode) is that the expression won’t know when you rename the List Records step. Which is why Tip #1247 is important.

Cover photo by unsplash-logoCupcake Media

Tip #1255: Say hello to PowerApps Component Framework

At long last we have that abbreviation sorted out. CCF PCF or PowerApps control Component Framework a.k.a. Goodbye Web Resources is now available for public preview. It sounds grand and does hold the promise of changing the way we extend PowerApps, both model-driven and canvas.

Read the announcement conveniently placed within the new PowerApps Component Framework (Preview) forum.

Tîpp Jäår action plan

Cover photo by unsplash-logoVadim Sherbakov

Tip #1254: Design Dynamics 365 email templates with the new email editor

In a recent virtual conversation with Steve Mordue, Steve inquired about using the new Unified Interface email editor to create email templates.

While Microsoft has not (yet) gotten around to adding the template creation process to unified interface, there is at least one approach you can take to design your templates in the new email editor.

  1. Create an email in Unified Interface
  2. Add your fancy schmancy formatting
  3. CTRL+a and CTRL+c to select all of the contents of the email body/description.
  4. Create a new email template in the Advanced Settings area.
  5. Select the template body field and CTRL+v to paste the contents.

This will maintain most of the formatting, including images. You can then add in your template specific merge fields.

Cover photo by unsplash-logoPeter Lewicki

Tip #1252: Creating a Planner task with Flow: wait a minute

If you use Microsoft Planner to plan your project tasks, you may want to automate creation of tasks. You can do this with Microsoft Flow.

You will notice that you can’t update fields like the task description when you create a task–this is actually a separate step, called update task details. But if you try to create a Flow that creates a task and immediately tries to update the details, the Flow will fail with a record does not exist error.

To avoid this issue, add a 1 minute delay between creation of the task and update of the details.

Cover photo by unsplash-logoXu Haiwei

Tip #1251: Run workflow when something did not happen

Flow is all the rage these days but there are some scenarios where classic workflow still rules. Classic workflow has the uncanny ability to readjust itself when underlying data you’re waiting for, changes.

This dialog took place not so long ago:

Steve “Reads his own blog” Mordue: I want to trigger a workflow to update an account record if a case has not been created in the last 30 days for the account. Any ideas?

Yours truly: So let me get this straight… You want to run a workflow when something does not happen. That’s a new one.

SM: Yes

YT: How about this.

  1. Create a field on account ‘Last case created on’. Have a workflow that fills that in with the current date on case create.
  2. Have another workflow waiting on that field that kicks in 30 days after the date. It will readjust itself as the field gets updated.

SM: I like it

Just to be fair. If you have bazillions of the accounts and quantamarillions of cases, you might end up with a large number of waiting workflows. Some people have beef with that so those might want to consider Guido “Future olive farmer” Preite‘s suggestion of a scheduled Azure Function to perform the check every day. GP did admit that it was a developer’s suggestion meaning that SM ignored it.

Cover photo by unsplash-logoAnthony Ginsbrook

Tip #1250: Forms won’t load in Chrome

With Joel being busy or lazy, I’m claiming credit for that one even though I have nothing to do with it.

Problem: Classic UI [allegedly – t.j.] has an issue in v8.x where Chrome will just keep ‘spinning’ on some of the forms without returning anything.

Solution: Add an empty JS file to the form.

Explanation: Forms with no custom JS may not properly initialize the OOB script objects. Obviously a Microsoft/Chrome issue but, in a pinch, add an empty js file and that tells Dynamics to go initialize all javascript objects (including its own).

Joel trying to be funny: Legacy form rendering also works if you’re feeling destructive.

Time to upgrade: Unified interface doesn’t have this issue

Tip #1249: Talk back from canvas to model-driven

Until now, embedded canvas apps were a mere eye candy. But with just announced new capabilities you can now talk back to the form. Kind of. More “bark orders” than “talk” but this is awesome start!

Embedded canvas apps now provide the ability to perform actions to navigate, refresh and save the host form. With these capabilities makers can now achieve even richer integration between the embedded canvas app, the host form and other assets in the model-driven app, unlocking an entire new set of scenarios to help meet business needs.

Anees Ansari, Principal Program Manager

Blog post: https://powerapps.microsoft.com/blog/embedded-canvas-apps-can-now-navigate-refresh-and-save-the-host-form/

Documentation: https://docs.microsoft.com/powerapps/maker/model-driven-apps/embedded-canvas-app-actions

Now, how about letting us talk to form context? 😉

Tîpp Jäår

Cover photo by unsplash-logoHarli Marten