5 ways to run a flow on multiple records inside a model-driven app

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hi friends, it's Scott Durow. Welcome to another episode of Power Apps Cafe. In this episode, we are gonna be looking at five ways of running a cloud flow from a grid of records inside a model driven app. So if that's something that interests you, stick around. Well, there are broadly two ways of running flows from model driven apps. Now, the first is having a single flow that can be run for each record that you've selected. So that will, if you have 10 records selected, that will run 10 versions of that flow. Another option is to have a single flow that accepts a list of records in this case 10 records, and then runs a action inside, a a loop for those 10 records. Both are equally valid and may suit different scenarios, so let's start with the first option. Okay. So there has been a button that says Flow inside model driven apps for a very, very long time. And it's been one of these things that really hasn't had very much attention for a very long time. So I talk about it as the legacy flow button. And the way that this works is that you have a model driven app. And you have a grid and there's a flow button, and you can create a flow from that grid. And what that does is it allows you to run that flow from that grid and uses the Dataverse Legacy connector. And it's a special trigger called when a record is selected. We don't currently have the same trigger inside the current in the new data connector. Also you can't add these flows to a solution because of using that legacy trigger. So it, I kind of think about them more as a personal flow, as a personal productivity flow. So if we come into our milestone app, Milestone Manager app that we've been looking at over this series of videos, If we go into the projects grid and we wanted to have a flow that we can run on each of these individual projects that we've selected, and we go over to the command bar at the top here. There is a option here for flow. And this is where this, this button here has been for a very, here for a very long time. So we've got two options. We've got create a Flow and see your flows. So you can see right from the beginning it's very much about your own personal flows. I'm gonna create a flow and we can see straight away that it's using the legacy Microsoft Dataverse trigger. And so I'm gonna continue and that's gonna go and create it. And we are creating it inside Power Automate. So it's outside of a solution and you can see it populates by using the default environment and the projects table. And then I can start to add steps, you know, all the things that we would like to do in, you know, maybe, I don't know, create an email, send an email via Office 365. And once we've done that, that will then appear in our lists of flows inside our model driven app. Let me just create one quickly as a dummy one, and I'm just gonna save this and, and it's actually just named it Microsoft Dataverse button. But you could obviously rename it. Now, if I go into back into my model driven app, I'm gonna obviously have to refresh this. And now when we go over to the flows, you can see here there's our Microsoft dataverse button, and that's only gonna show for me. So I'm not gonna talk about that anymore. Personal productivity flow, you can use it for on, on a per user basis. The next option is where you've got a grid in a model driven app, you can use , the bulk edit option to trigger a flow by defining your flow to run on update of a record. So we could create a, it could be a dummy attribute or it could be an attribute that's already there and edit it in using the standard edit functionality. And then when that attribute is changed in the flow, we will then filter only to trigger when the attribute has changed, and so we can then run functionality for each of those records. So I'm gonna create a new flow here and I'm gonna use the automated flow because we want to make sure that this triggers on when we update our project record, because the idea is that we are going to trigger a flow when the project status attribute is updated because I create this dummy attribute. And the idea is we use bulk edit to update that particular attribute. And then for every single project that has that attribute updated, it will then go and trigger this flow. So we might want to make sure that we use the dataverse connector and there are two. There is a, when row is added, modified, or deleted, Microsoft Dataverse, but there's also down the bottom here, there is when row modified, and this is actually the legacy connector, so don't wanna use that. So I'll, I'll create this. And so the change type we want to have when it's modified, and that's, that's the, the filter we're using. And we we're gonna say when projects are modified, and we're gonna say, Well, this is gonna run for every single person that's up updating this. I'm gonna select the advance options here, and I'm gonna start to trigger this only on particular columns. So I only want to trigger this when the report generation status is updated. And I also want to provide an additional trigger here to say when the report generation status is starts with trigger. And then the next, let's just create a, a dummy step like we did before. So let's put a composing and just put the, let's put the ID of our project which is going to be, Let's zoom out here about, so we're getting a different one here. Let's get the project id. There we go. And then we'll save that. We're also gonna add in another step here to say the Microsoft Dataverse connector here, which we're gonna update, update a row because once it's been triggered, we'll go and create the report, which will all, that will be all of the bits in between these two steps here, which we're emitting just cause we're not gonna do that in this video. And we're gonna say, we're gonna update the project that was triggered on this and we're going to go and clear out that project report generation status. So I'm gonna say it's completed like that. So that once it's finished we know it's actually has actually done its work. So I'll save that away. So let's test this. Now if we come into the set of projects here, I can now use this edit, bulk edit function. I mean, if, if you select this and you've only got a single record selected, it's just gonna open that individual records on a standard form. But the great thing is now if we select edit here, we now get this dialogue that allows us to edit bulk records, which is very, very cool. So if I come into admin, I've actually got my project generation status field here. So I can go in and select, I can just type in trigger, and if I select that like that, and you can see it updated all of those individual records. And so here we go. All of these records have got that set to trigger one, and if I refresh this, you'll see that gradually. Oh, okay. There we go. That was very quick. They're now all completed. So that's a, a pretty easy way of triggering your flows. Very low effort. Obviously it's a little bit cumbersome because the user has to know which attribute to update to trigger the flow. So the next option is to use a power Fx button. So if we have the same scenario, we have a grid of projects, what we can do is you can use the new commanding feature to add a button. And then we can put some power effects that to actually patch that same attribute that we manually updated using the bulk edit. And of course, that would have the same result. It would then trigger the flow. So let's look at doing that. So here I'm in my App designer which is for the, for the Milestone Manager app. And I'm going to go to the project table that I've added in here, and I'm going to use Edit Command bar on the, the Ellipses menu of project. So, and that, what that does is opens up my command editor, so allows me to add buttons and I'm going to select the the main grid of my project. So if I go, actually, let's use, let's use the subgrid so we can do this underneath a particular account and run it for a selected account projects. So this is showing at the top here. You can see this is the Subgrid view for project. I can come in here and now I can go and create a new command and I can call this generate reports. And let's call it in Power Fx in brackets. Why not? Let's use it, give it an icon. What should we give it? Let's give it that icon and I'm going to select to use open the formula bar. Cause I wanna run a Power FX formula here. So what that gives me is at the, the top here is it gives me on select, which is the event that happens when I click my my button. So there, I'm gonna pop in a bit of. Power Fx into this. And if we look at how this works, what this gives us is a. It gives us the patch statement. So we're gonna patch all of the projects that are selected in the current grid. Now, there is is an interesting thing here because what we're doing here is we are not going for all selected items and then patching each of the items. What we're doing here is we are patching. The projects and we're passing that in a collection of updated items because what that means that it will do it, it will do them an in parallel to each other. If we put the ForAll around each of the patches, it will basically do a patch for each of the selected items in a sequence, and that would obviously be a lot slower. And so what we're doing here is simply updating there to be a trigger. The report generation status trigger and adding on a random element so that it's always gonna change when we do this trigger. So this is very similar to what we had when we were updating it through the bulk edit. And the next thing we need to do is come down to there's a visibility element here, and we need to make sure that we put a rule in here to say, show condition. On condition of this formula. And so we open up the formula bar here and we're going to use a special condition here, which is basically saying that, we only show this particular button, when the items selected is not empty. Because we want, we don't wanna show this button when there are no items selected. So we'll save and publish and wait for that. In our list of projects, I can just select an account and I've got a subgrid here of all of the different projects that are related to that particular account. And so in here you can see the project generation status is, is empty. So let's just select these first four in this state, in this this list. So what we've got is our generate report power Fx button as you'd expect. And so we, if we run that, so now you can see here the report generation status has got the trigger, which is great. And if we refresh this, you'll see that eventually these will be complete. Let's refresh again. There we go. Completed. So we've got the ability now with our power Fx button to run a flow on each of those items and notice if I don't have any selected, that button is not visible. Well, what happens if we don't want to have to keep on refreshing that that grid we want to run the flows and have some feedback to the user so that they know that it is all completed? Well, currently, there's no way of doing that inside power Fx. There's no way of displaying a kind of a progress bar yet. And so if we wanna do that, we are gonna have to use JavaScript. Or in this case I'm gonna use type script. So we've got the exactly the same kind of scenario. We've got our model driven out with our grid. We're gonna use a command bar using modern command, we've, but rather than using power effects, we're gonna actually run some JavaScript from a JavaScript web resource, and that will do exactly the same thing. It will update the records. and that will trigger that flow. I have a free course that I'll put link to below I on writing type script, web resources if you wanna learn how to do that. In this case, I'm just gonna show the code and show that hopefully that actually it's not too complicated. So here I have a type script project, and the project has got a type script file called Project Ribbon, and we've got a class called Project Ribbon in here. And I'm using a library called dataverse-ify with dataverse-gen. And that's a library and open source library that I've created that my free course shows you how to use. And it just simplifies making calls to the web api. Making calls to update Dataverse without having to, to construct http request or using a low level web API call from using the XRM utilities. And so what we're doing here is that we've got a top most trigger function, and this is the function that's gonna be called from our command button. And it accepts a list of entities in a, in an array. And I'll show you how to do that in a minute. And what it does, it makes it call to an internal function just using Promise.Resolve. And what that means is, is that it's a fire-and-forget, we don't want to wait for this particular function to run because otherwise the time there will be a timeout that the JavaScript call will, will happen. So the model of an app will think that the function is not actually done what it needs to do, but because we're doing that fire-and-forget this function now runs. It does something very similar to the power Fx. It sets this trigger to be, to get, have a random element to it. And then what it's doing is it is going and creating a set of updates. So what we've got here is we've got a a set of update batches that it will pass in this particular shape of object, which is saying that it's a logical name is project, and we're giving the id of the project and we are setting the project generation status to be trigger very much in the same way as we did with the Power Fx. So we've got, now we've got that set of updates inside this batch an array. Now we can just simply make this call to execute multiple. And so that will send a single batch update with all those updates in it. And now what we can do is we can call a FetchXML query to find out how many. Of the projects still have their status set to that trigger that we just updated it. And that's, so that essentially doing the same as when the user is clicking the refresh button, what we're doing is we're counting how many are still in the trigger status and they haven't been moved onto the the completion status. And so then what we do is we then show the the progress. And so what we're using is we're using this showProgressIndicator utility that comes as part of the XRM utility, and it will show the number of projects that are currently have been completed versus the number that we originally sent it on. And we're also gonna time out. We're only gonna do this every two minutes now. All this code I'm gonna put up available in a blog post. So you'll be able to go and grab it as well. And so the, all that remains that the end is just to close the progress indicator so that we know it's been done. So back over in the Subgrid editor for projects, I've added in a new button here called Generate Reports, but this is calling the JavaScript and it's basically the same as the power Fx version, except I am making use of a JavaScript web resource. And what we're doing is we are, now, we're going to call a function, which in this case is the create report trigger function that we just looked at inside our type script. And we're passing in a parameter called SelectedControlSelectedItemIds. And so that's that array of all the IDs of the projects that we have selected in the sub grid so that we can go and perform that batch update. So once we've saved and published that, and we can go and play that and go over and we will get this little message here to say a new version of the app is available, please refresh to update. So we'll refresh that and then go over into the same place as we were before inside our accounts. And we'll open Contoso as we had before, and if we look at the items down here, let's go into the second page. There we go. So let's just select some items here and now go into our command bar. And you can see here we've got generate reports (JS). So let's go and select that. And there we go. Generating reports. You can see here it's giving us the number that have actually been completed. And you can see it's just incrementing. So the flows are running in the background and it's running that FetchXML to determine how many have actually been completed. So we didn't need to refresh this. Of course, if I refresh this now refresh this grid, then we'll see that they all are marked as completed, obviously, because our code was waiting for that. So up until this point, the flows that we've been running have run for every single record that we selected. So if you select five records, it will have five flow runs. Another option is to use a custom page to run a single flow passing in a list of multiple records. And so we do this quite easily from a grid using a little bit of JavaScript. So we would use a command button as we did before, and we'd have a JavaScript function that would accept as again, as we did before, a list or an array of all the selected items. And then this time, rather than actually making the call inside JavaScript, we're gonna use the Navigate API to show a custom page as a dialogue. Now I've got other videos of showing you how to use custom pages. And in this case, we're going to accept a parameter, which is Id passed from that JavaScript. And then we'll use Split to split it out into individual GUIDs, unique identifiers of the various different projects. And then we'll pass that across to a flow using and the power apps trigger. And so we can then split that up, and and perform multiple actions in a loop inside our flow and then inside our custom page, we can then do the same as we did in our JavaScript, we can kind of monitor using a timer, monitor those records to check if they've been completed or not. So this time we are going to use our main grid project main grid ribbon. And so I've got a button here called generate reports similar to the JavaScript report generation button that we had before. And the action in this circumstances we're gonna run a different function in the same ways we did before passing in SelectedControlSelectedItemIds. So an array of the the IDs that are selected. And we have, again, the visibility of this button is based on the selection in the grid. So if no items are selected, it won't show the button. So if we go over into the JavaScript, this is actually quite a simple JavaScript in that it has the same function parameter, which is the entity IDs, the string array. But we are now just simply going to pass in a set of parameters here which are the the page type is going to be custom page and It's the name comes from the logical name of our custom page in the solution, when we add a custom page, we can easily get that. And then what we're doing here is we are simply joining all of the IDs together into a single string using comma as a separator. And then the, the navigation options Uh, we are, we've simply saying that it's gonna be a 2 means it's gonna be a dialogue and position 2 means it's going to be a, a side panel and we give it a little bit of width and we can give it the title as well. And then this last item here is simply saying, Okay, we now gonna navigate to that custom page using those navigation options that we've just defined above. So here I've got a custom page. We've got creator kit, details list and just a button saying Create reports. And so this would be the custom page that you would show in the sidebar. And so when we show the custom page, it's gonna be become, it's gonna run this on visible event. So we're gonna put some code up here to go and grab the various different parameters that we've passed into it. So we've got this record ID parameter that got passed from our JavaScript, if you remember. So if you go into our JavaScript you can see here that we are passing in the record ID parameter here. So we will split that eventually based on the comma because obviously we passed it in with, with a, a comma delimiter, and now we need to split it up into a set of records. And then what we're gonna do is take that set of record IDs and go and grab individual project records from the project data source. So I'm gonna go here and add in a, the project table. So that will then resolve. And so we've now got a the collection called colProjects. For each of the IDs that we had passed in, we are going to get a project record in here that will have the ID and the name and the status. So we can go and bind this colProjects to our data grid here, and then we need to set the columns. I've got another video that shows you how to do this. Set the columns to be a set of simple definition of the status, and then the name. And, and so if we run this by moving away and then coming back. We should now have a set of and let's go and add in, make sure we've added in the fields, so Id name and status, add that in. And there we go. We've got a name of the individual project, and then we should also have a status column as well. Just take a look at that definition here. Okay. So it's because evidently I, cause I took this from the completed app so it's actually trying to show it as an icon, which obviously I haven't done yet. I'll show you how that works in a minute. But in the moment, I'm just gonna display the status here. And let's just make the width of that. Yeah, that's fine. So now if we go back to that here, the call name is Status Cell Type is not image. It's just gonna be a standard text. There we go. So we've now got it's showing complete because that's what we had, we'd done these previously. The next thing we need to do is we actually need to be able to run the flow on these items and then refresh the display with the, the latest value. So we have to go and create that flow. And as I said before, we're not going to pass in each individual. We're not gonna run the flow multiple times. You're just gonna run the flow passing in a, a collection. So if we go to on select here, and we put this below code in here, what we're doing here is we're just updating the status to be in progress. And then what we're gonna do is we are going to, get a set of collections and convert it into a JSON string. And that's what we're going to then pass into our our flow. And so let's take this varJSON and just, just put it into a text box if we go down here so that we can go and get the, see what it looks like. So I'm gonna put the value of this to be. varJSON obviously is empty at the moment, but if I run create reports, you'll see now that it has got a, a whole load of JSON. So if I extract that out and go over to create another flow, So let's go back to our solution. And there's cloud flows and I create a new one. And this time I'm gonna use an instant flow because we're gonna trigger it from power apps. So there's, it's the power apps trigger and we're gonna call it generate report 2 cause I've already got one. So power apps and then create. So we've got the power apps trigger, and as I said before, we, we are going to, we're sending it a string of Jason from our power apps. So we're gonna use the Parse JSON, and we're going to ask in power apps. So we're gonna call this the the selected record. So let's rename this selected records. So you can see here it's now created selected records content. So that's now a parameter. To this flow and we can just paste in, generate from sample, we can paste in that that JSON that we picked from the the generated JSON in our app. So you can see there is now created a nice schema for us. So now we have our parse JSON. Now we can go and do another data operation. And we can map the the, json object that has been passed into an array. So I'm going to select the output of that that parsing. And I'm gonna go and grab for each of those that just the id. I'm gonna call this just the project array. Now we can just simply use this so that, let's say we wanted to do in Microsoft Dataverse, we wanted to go get some list rows. We could say, well, the project table, and we could use a FetchXML query so we could pop some FetchXML in here. So this will get all of the projects where the project ID is in, and there's a set of values here, and I'm gonna put a dynamic expression in here, and we are going to put in a join. So the, this joins the outputs of the selected record id, which is actually we need to make sure it's called projects array like that. That's the output of that. And then we'll get the body of that and we'll join it together using value. So what that'll end up with is a list of values inside here. So once we've saved our flow and we come over back to our custom page here, we can go and add a flow. And say, create project reports and select that. And rather than inside create reports, rather than just simply setting the variable there, what we can do is we can say, create project report and we can then send that text over and so there that will, that will trigger that flow, that will, the json will be passed split into an array and we can perform various different things in a single flow. So we can actually do a loop over that array and at the end of that, we will then update the trigger status to say it's completed in much in the same way as we were doing before. So all that would remain is in this app, is to actually go and refresh and monitor this. That does pose somewhat of a challenge since there is a lot of caching that goes on inside canvas apps and so, you know, for performance reasons. So if we want to refresh a grid, we need to come up with some way of ensuring that we perform a query that will always get the results rather than getting it from cache. So we flip over into what I prepared earlier to see how I did that. So this is very similar to what we just saw there. But if we go and if we look at the grid, there's a subtle difference here in that rather than just simply having a text version of the status, what we're doing here is we're adding a couple of columns to actually convert that into an icon column with an SVG to show like a spinning icon. And and the actual color of the status, depending on the status that if it's completed or in progress. And then also on the create reports on select here you'll see that it's very similar. But what we're gonna do is we are going to set a context to say that this flow is running and that will then start a timer. And the timer will tick away every two seconds. And on end of that timer, the on timer end. If we look at the this is going to run Select(btnRefreshFunction). So this is just simply an easy way of encapsulating some common common functions that you use over and over again. So I could call this from multiple different places. And so what we're doing here is we are creating a random filter seeds. So we're saying here that this is just a, a simple random string, and we're using that random string inside our our filter. So each time we run this query, this random element will be different. And so that forces the expression to be reevaluated against the server. If this was always the same, then you might get these results from a cache. And so every time we refresh, we're gonna get a a new set of results. And so it's kind of one of those workarounds, if you like, to caching. So let's take a look at that in action. I'm gonna run, generate reports here. And so you can see here it's running that JavaScripts and showing the custom page with all of the items that I've just selected. And I'll, I'll select, select, create reports here, and it will then run that flow. And you can see here they're all in the, in progress. And now that time has started ticking away and the, the filter is going to run, and it's gonna gradually see these results get completed. So there we have it and it's all, it's all working and showing the the updated status. So that I think is five ways of running a flow. So. If there is a different way that you've used to run a flow you may have used Ribbon Workbench, the Smart Buttons, web hook functionality. That may be a way you've used or maybe you've used a different way in the past. Please let me know in the comments and subscribe and like, and hopefully if you've liked what you see. I will see you next time. Have a great rest of your day. Cheers.
Info
Channel: Scott Durow
Views: 15,321
Rating: undefined out of 5
Keywords: PowerPlatform, PowerApps, Dataverse, CreatorKit, PowerAutomate
Id: U9AThfx8ZQE
Channel Id: undefined
Length: 32min 55sec (1975 seconds)
Published: Sat Oct 15 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.