Tip #1460: Loops and ThisRecord in low-code plug-ins

When you use loops like ForAll function in a low-code plug-in, ThisRecord will change its meaning from the table row associated with the plug-in run, to the row inside the loop. Disambiguating is fairly straightforward… once you know how.

Simulate slow plugin

To experiment with bypassing Dataverse plug-ins, I needed something to bypass. Lazy Developer in Me™️ whipped out this gem of an automated low-code plug-in that creates a related task when a contact is created. (Let’s not talk about why I let my lazy inner-self take over from the Real Developer™️.)

Collect([@Tasks], 
   { 
      Subject: "Do this" , 
      Regarding: ThisRecord 
   }
);

That was not slow enough, so I decided to do that 50 times.

ForAll(
   Sequence(50), 
   Collect(
      [@Tasks], 
      { 
         Subject: "Task " & Text(Value), 
         Regarding: ThisRecord
      }
   )
)

which failed miserably with “_regardingobjectid_value should be a Dataverse Record” error. That’s because ThisRecord now was part of the Sequence, duh.

Get paid by the line

I am not that good with Power Fx so in my first attempt I wrote the plug-in like a baboon paid by the lines of code.

Collect([@Tasks], { Subject: "Task 01" , 
   Regarding: ThisRecord });
Collect([@Tasks], { Subject: "Task 02" , 
   Regarding: ThisRecord });
Collect([@Tasks], { Subject: "Task 03" , 
   Regarding: ThisRecord });
Collect([@Tasks], { Subject: "Task 04" , 
   Regarding: ThisRecord });
Collect([@Tasks], { Subject: "Task 05" , 
   Regarding: ThisRecord });
// Continues to Task 50
  1. ✅ Does the job (on this occasion).
  2. ✅ Easy to read.
  3. ✅ Pays well.
  4. ❌ Not cute and deeply dissatisfying to look at.
  5. ❌ Lot of copypasta.
  6. ❌ Cues the questions like “You do know ForAll exists, don’t you?”.
  7. ❌ Most importantly: what if you really need a loop like to do something with the related activities in an update plug-in?

Do it properly

Thank goodness, the Real Developer™️ soon took over and, after asking infinitely smarter friends, found some documentation from 28 years ago (in dog years). Enter the magic of As operator which brings ThisRecord back to being the Dataverse row.

ForAll(
   Sequence(50) As counter,
   Collect(
      [@Tasks],
      {
         Subject: "Task " & Text(counter.Value),
         Regarding: ThisRecord
      }
   )
)

Side note: if Power Fx was developed in Australia, it would totally have had an AsIf operator.