If you’re developing PowerApps you must at least once find yourself in a situation of having multiple different controls executing same or similar code. In this post I want to answer to following questions:
- Is code duplication that bad?
- When PowerApps Components are not enough to avoid code duplication?
- What is another way to centrally manage code in PowerApps
Is code duplication that bad ?
I’ll answer this question using my case when I’ve made a PowerApp app that calls SharePoint Search REST API (via Microsoft Flow) and display results. App looks like this:
As you can see you can search for specific phrase, limit items per page and navigate between result pages. Let’s stop for a second on pagination feature. How do you think – how it was built? Probably most of you will quickly figure out that pagination is nothing else than searching with a “number of items to skip” parameter. Knowing that, you can think of the “Search” button as searching with a 0 (zero) items to skip. In other words – we need 3 buttons with very similar code. Below I present such code – please notice comments I’ve provided:
//clear search results collection Clear(colSPSearchResultItems); //read row limit number from input text box and save as variable Set(gblRowLimitNumber,numRowLimitNumber.Text); //make call to SharePoint Search and save results in variable. //Flow has following parameters: Search_Query, Row_Limit, Row_To_Skip) Set(gblSearchResults,Searchforitemsintenant.Run(txtSearchPhrase.Text,gblRowLimitNumber,Text(gblItemsToSkip))); //Now we need to extract values from results string and save as separate //column in table ClearCollect( colSPSearchResultItems, AddColumns( Split( gblSearchResults.results, "/n" ), "UniqueId", First(Split(Last(Split(Result,Char(34)&"UniqueId"&Char(34)&","&Char(34)&"Value"&Char(34)&Char(58)&Char(34))).Result,Char(34)&","&Char(34)&"ValueType")).Result, "Title", First(Split(Last(Split(Result,Char(34)&"Title"&Char(34)&","&Char(34)&"Value"&Char(34)&Char(58)&Char(34))).Result,Char(34)&","&Char(34)&"ValueType")).Result, "OriginalPath", First(Split(Last(Split(Result,Char(34)&"OriginalPath"&Char(34)&","&Char(34)&"Value"&Char(34)&Char(58)&Char(34))).Result,Char(34)&","&Char(34)&"ValueType")).Result, "Rank", First(Split(Last(Split(Result,Char(34)&"Rank"&Char(34)&","&Char(34)&"Value"&Char(34)&Char(58)&Char(34))).Result,Char(34)&","&Char(34)&"ValueType")).Result ) );
This code realize everything I needed. Although implementing it was not a big deal (I’ve done it once and copied 2 more times), debugging and further maintenance was a nightmare. Every time a change done in one of those buttons had to be copied to the others. When at some point something broke up (ie. some results were wrongly parsed) I was reviewing all 3 copies of the same code just to make sure it is the same (sic!).
Mastering PowerApps Components you must
Yoda has spoken. And at some point he is right – PowerApps Components are very good way to avoid code duplication. Especially if you know PAC development patterns I described in my previous post.
BUT! What if you have totally different controls ie. a shape, a button and a gallery and all of them should use the same code. PAC are good until you want to have different properties per control (i.e customize button text in one control and image in another) so this won’t work for such control set.
In such situation I have a recommendation for you.
Centrally managed code in PowerApps
To build centrally managed code in PowerApps follow below steps:
- Add a new button and make it invisible
- Put your redundant formula in OnSelect event of the button
- Use Select(YourInvisibleButton) function to execute formula inside OnSelect event of your invisible button
- For any dependencies (you can think of them as the functions arguments) use variables (global or local). Ie.
Using presented approach, my “next page” icon code from example search app, looks like this:
//Set items to skip in variable Set(gblItemsToSkip,gblItemsToSkip+numRowLimitNumber.Text); //Call button that contains parameterized arguments Select(btnCallFlow)
Code of my “previous page” icon is almost the same (the only difference is the minus sign instead of a plus)
4 lines of centrally managed code instead of ~50 lines.
Simple. Clean. Beautiful.
Nothing is perfect
Described method won’t work if you would use variables to pass some “arguments” followed by Select function inside Concurrent function in the same time. It’s obvious but worth to mention just in case.
And that’s it! I hope you enjoy this post.
Let me know in the comments if you like this approach or not.