Microsoft PowerApps and Flow (now Power Automate) have been on the scene for a few years now, and naturally, there is a lot of interest in how these platforms compare to K2.
Both platforms promise to let you connect to your business data and build applications rapidly with low or no code. I have seen some impressive applications built-in both platforms, but to date, I have only really dipped my toes into the PowerApps and Power Automate platforms.
I have been building K2 apps for years and know the platform well, and I was interested in seeing how the design experience compared to PowerApps and Power Automate. So, I set myself a challenge: to build a simple app using PowerApps and Power Automate in a day – without having to resort to spending hours watching tutorials on YouTube. I would of course need to do some googling, but if I felt I was getting nowhere then I would move on and ignore that feature or functionality.
The outcome of the challenge was to then compare both the design experience with K2 – how easy/hard was it to build the application in PowerApps & Power Automate compared to K2. In addition, how do the features of both platforms compare? What could I do in one platform that I couldn’t do in another (or not easily anyway!).
The solution I chose to build allows staff on a school or university campus, or any other institution with many buildings, to capture any issues they find with the buildings and report them.
The user should be able to open an app on their mobile device and with a few clicks submit either a building defect or hazard they have spotted, or an improvement they want to request. They should also be able to take a photo, mark it up if necessary (e.g. to highlight the defect), and submit that along with the report.
When a report is submitted a building manager should receive an email that allows them to review the report and choose to either pass it along to a maintenance officer for action or to do nothing. If it is passed along to a maintenance officer, they are alerted by email with details of the issue.
Some further requirements I wanted to implement if possible were:
- Ability to submit the form while the mobile device is offline
- Capturing Comments and Assigned To details from the Building Manager when reviewing the report
- Attaching the photo to the email to the Building Manager and Maintenance Officer.
- A “rework” option for the approver to request more information
In the interest of time there were things that I did not want to focus on, including:
- Advanced UI navigation
- Advanced Workflow features (escalations, task redirection & expiry)
To store the data for this app I chose to use an Azure SQL Server database, as I wanted a relational data structure, and I wanted something in the Cloud that both PowerApps\Power Automate and K2 can connect to.
The first decision was how to create the app in PowerApps. There were 2 basic choices that seemed appropriate for what I wanted: Canvas app from blank or Start from data.
My initial choice was to create a blank app but quickly realized that I did not possess the skills to create the screens I wanted without doing some hours of learning. So, I went back and created the app from data. To create the app from data you need to choose a dataset to work with. To get my dataset I first needed to create a new connection to my Azure SQL Server database. This process was straightforward and easy.
Once the connection was created, I could then choose the table I wanted to work with. I noticed at this stage I could only choose one table (I chose the Report table) and wondered what I needed to do to be able to connect to the other tables in my database. Once the table was selected PowerApps did its magic and created the app for me. The result of this was I now had 3 screens I could start to work with: Browse, Detail, and Edit.
The PowerApps screen framework is simple and intuitive for use on a mobile device. The Browse screen presents a list of records from your main data object (in this case Reports) with the ability to sort or search for records. An existing record can be accessed by clicking on the record row, which takes you to the Details screen. From this screen, you can choose to edit the record, which opens the Edit screen. A new record can be created by clicking on the plus button at the top right of the Browse screen, which also takes you to the Edit screen. The Edit screen thus serves two purposes – to edit existing records and create new ones.
I was not interested in changing the basic layout or screen framework for the app as this would be too time-consuming. Instead, I wanted to focus on allowing the users to create new reports and start the review process (using Power Automate), which meant making some changes to the Edit screen.
On opening the Edit screen, I found that PowerApps had decided which fields from my Reports table should be displayed. After a bit of poking around, I found I could add the fields I wanted and remove the ones I didn’t. I could also arrange them in the order I wanted by dragging the “DataCard” for each control to the desired position.
I had created a “Photo” column as a nvarchar(max) datatype in my database to store the photos – as this is what you would do for a K2 app – but soon realized that this would not work in PowerApps. I needed to create a column that used the “Image” datatype. Once I did this and refreshed the data source, I could add this new “PhotoBlob” field to the screen and it rendered as an image control.
In my Reports table, I have two foreign key columns referencing the Building and ReportType tables. PowerApps created these columns as text controls fields that would accept a number value.
Obviously, this would not work, so I had to work out how to change these controls to dropdowns that would lookup my Buildings and ReportType tables. There seemed no obvious way to do this, so I consulted “Dr. Google”.
It turns out I needed to display the fields for the screen and change the Control Type for these fields to “Allowed Values”. This was only half of the battle though, I then needed to tell the control what the allowed values are. To do this you need to select the “Items” property and add a “ShowColumns” formula which specifies what lookup table to use and what value to display and store.
However, to use the additional tables, I first needed to add a data source for each one, by clicking the “View -> Data Sources” menu item. As the connection to the database had already been created it was a simple matter of selecting the tables I wanted after choosing the existing connection.
I could then add the formula to the drop-down controls to show the correct values – but only after unlocking the control on the Advanced tab to allow me to change the properties. The entry of the formula was aided by, although it did not pick up the “BuildingName” property until I had typed it out completely.
This change however broke the “Update” formula for the same control. It turns out it needs to be changed to reference the new data source property.
The next step was to work out how to capture the additional data I wanted to store for the request that I didn’t want the user selecting – namely the SubmittedBy, SubmittedDateTime, and Status values.
My first intuition was to look at the “rule” that did the “data submit” and see if I could set the values there. When you look at the “OnSelect” property for the button that saves the data, it has a formula that just says “SubmitForm” with the name of the form as a parameter.
After a bit of googling to see if I could somehow modify this to suit my needs, I realized I needed to take a different approach. There is a “Patch” formula that can be used that takes a JSON string as a parameter, but it looked too complicated for me to work out in the time I had.
The approach I took was to add the fields for table properties to the screen and then set their default value and make them read-only or invisible. This was not too hard to do, but what I didn’t like was once I made a control invisible you cannot see it on the screen.
PowerApps seems to try to render the screen in the design mode as you would see at runtime, which is helpful in some ways but annoying in others.
Testing of my app confirmed that data was being submitted to the database. After a bit of tidying up and modifying the Browse and Details screen, I was ready to create my Flow.
To create the Power Automate Flow, I chose to use the “Actions -> Flows” function from within PowerApps, as I figured this would make the starting of the Flow and passing of data to it more seamless.
It was easy enough to create a new Flow, but for some reason after creating the Flow and selecting it, Power Apps wanted to add the formula to start the flow to the “OnVisible” Property of my Edit screen. More on how I fixed that later.
The first challenge with Power Automate was working out how to get access to the data from my Power App.
Power Automate created the new flow with a “PowerApps” trigger, but it offered no clues on how to access my data.
The first thing I wanted to do was get access to the newly created record in PowerApps. It turns out that the “PowerApps” trigger step provides 2 dynamic fields that can be accessed, one of these being “Getrow_Rowid” which I figured (correctly) would be a parameter passed to Power Automate from PowerApps. So I created a SQL Get Row action to get the data for the new record.
I followed this up by also getting the Report Type and Building records using the SQL Get Row action.
Now it was time for the “Approval” step. There are a few extra Approval step actions available since I last looked at Power Automate, and I chose the “Wait for an approval (V2)” option. It seems the V2 options allow for an approval to be canceled.
Configuring the approval step was easy enough except for the Requestor and Item Link fields. I had assumed you would be able to access information about the person who started the workflow (the Originator in K2 workflows) but after digging around I could not find these details anywhere. So, in the end, I went back and added a new column into my database to record the email of the user who created the record. This meant some additional changes to my Edit form in PowerApps.
The next snag was the Item link. It does not seem possible to direct the user to the PowerApps page to view the data for the Report they are being asked to approve. It seems this Item link is only of use when using something like SharePoint to store the data and you can direct your approver there. Also, there was no way to attach the Photo (adding the “PhotoBlob” property to the email body caused an error).
After the approval step, I wanted to do some updates to the Report record (e.g. status) and send some emails. The only snag I hit here was adding the photo as an attachment to an email. The email action has an attachment field where you can add the content and attachment name. Adding the “PhotoBlob” field to the content worked, but I did not have access to the original file name, so I had to hard code a value with the jpg extension (which seemed to work Ok with a png file).
After saving my Flow I went back to Power Apps and tried to work out how to call my Flow. I only wanted the Flow to start for newly created items, which meant I had to work out on my Edit screen when it was a new record versus an existing record being saved. It turns out PowerApps uses a “DisplayMode” property to differentiate between editing an existing record and creating a new one. The forms also have an “OnSuccess” property which triggers after a “successful submit”. So, the challenge was to work out how to start the Flow after a successful save for only a new record.
Using an IF condition, I was able to check for the mode of the form (0 = New) and call the Flow if it was New. To call the Flow I needed to pass in a title for the approval (I think this is because my workflow has an approval step?) and the ID for the newly created report. These values could be accessed using the EditForm1.LastSubmit properties.
What I’ve Learned
Creating a connection to your data sources, in my case, as the Azure SQL database is straightforward in PowerApps and Power Automate. Once the connection is created it can be reused across other apps, and new data sources (e.g. tables) can be added easily to your app. You do not get a choice of authentication mode, so you must hard code a user name and password. Connections appear to be shared across PowerApps and Power Automate, so you do not need to create in each environment – however, this appears to only work per user, meaning my connections would not be visible to other users.
Once a connection is created, it is not possible to modify it. So, if my database moved to a different server I would need to create a new connection and new data sources and remap my forms to the new data sources (something that does not appear simple to do).
The data connection in PowerApps translates roughly to what we would call a Service Instance in K2. K2 allows modification of the service instance so that you could potentially change the server and or database name and the data sources, update your service instance, and your related forms and workflows would not need updating. K2 also allows you to specify different authentication methods for your connections – although in this instance with Azure SQL a static user name and password is the only available option.
The form design experience is quite different from what I am used to in K2 Designer. K2 allows you to build a single form, and by selecting a responsive design it can be run on a desktop or mobile device. PowerApps on the other hand seems targeted at mobile devices, with phone or tablet as the options available when creating an app.
In terms of form design, there are three main areas of difference between PowerApps and K2 –the form layout, the data sources, and the “programming” logic.
With respect to Layout, PowerApps uses the concept of “Screens” which translates to Nintex K2 SmartForms. When my app was generated, I ended up with 3 screens – Browse, Details, and Edit. The Browse screen had a control on it called a Gallery, which lists multiple records is similar in functionality to what would be a ListView in K2. The other two screens displayed a single record using a Form control and are like a K2 Item View. This is where the similarities end.
Like in K2, when you build a screen in PowerApps you can specify the data source to use for the gallery or form, and the controls are “bound” to the data source property. Because my main data source object (the Report table) has 2 foreign keys and I wanted to display the value from the related tables (i.e. Report Type and Building Name) instead of the key values I had to add these two tables (ReportType and Building) as data sources, change the controls to a “Use allowed values” type, and then update the formula for the “Items” property of the BuildingID and ReportTypeID controls (doing this then broke the “Update” property). Compared to K2, where I could simply create re-usable SmartObjects for ReportType and Building and use them as the data source for my drop-down, I found this process a bit tedious and time-consuming. In fact, with K2, if I had an association between my SmartObjects then when designing my view K2 would have automatically created my “ReportTypeID” control as a drop-down and used the “ReportType” SmartObject as the data source.
Perhaps the biggest challenge with PowerApps for me was dealing with the programming logic of the screens. Unlike K2 SmartForms, PowersApps does not have a rules designer (although there is a “Rules” tab on the control’s properties labeled “experimental”) but instead lets you deal with events and set values by using formulas for control properties. The formulas used in PowerApps are similar to what you would find in an Excel spreadsheet. The biggest downside to formulas for me was the fact I had to learn a whole new syntax -which meant a lot of googling. It is also not obvious what “Properties” of control are actually events, like “OnSelect” as opposed to true properties such as “Font”. Trying to work out what is happening on any one form proved quite difficult as I had to flick through many controls and look at the individual properties for each one.
Compared to PowerApps, I find the K2 SmartForms rules designer much more intuitive and easier to understand. Declarative rules in K2, such as “when the button is clicked, validate the form and then call the Save method on the Leave Request View” are much easier to understand and modify. Conditional logic in PowerApps formulas relies on If statements, which quickly get tedious when you have multiple conditions and outcomes.
The first thing that stands out when building an approval workflow in Power Automate is that the approval step is limited in the configuration. Specifically, you can’t choose the actions available – the approver can only choose to approve or decline – and you cannot provide a link to the Power App form to provide more information, or even collect additional information as part of the approval step (apart from the comments text box that appears in the email). Furthermore, while I did not attempt it, there is no easy way to implement a re-work pattern (sending the request back to the user to modify their request). Whilst it appears possible, the configuration required to achieve this looks complicated and time-consuming. There also does not appear to be any way to configure a reminder for a task, or a way to redirect the task if it is not actioned in a given timeframe.
Another thing that stands out is that apart from the email, it appears the approver’s only other way of accessing the task is by going to the Power Automate home page and selecting the “Approvals” page.
In terms of the design experience, one missing feature is the ability to copy actions. I wanted to copy my approved email action and paste it in as the declined email action, but this does not seem possible. There is a “Copy to my clipboard (Preview)” function for an action, but it does not seem possible to paste anywhere. It was possible however to copy content from the Email body from one email action to another – although this caused an error when I saved the Flow!
Power Automate offers some level of reporting that lets you see the Flows that have run and list any errors. While useful, these reports do not give you the same level of detail as K2, with no information about who started the workflow, how long it ran for, or when they started or finished.
You can select an individual Flow instance and get a report like a K2 ViewFlow report. This will give you the ability to click on each step and see the inputs and outputs for each.
The experience of building this application has confirmed for me that the design experience for building apps with PowerApps and Power Automate is not as seamless or sophisticated as the K2 platform. Achieving basic functionality, such as providing interfaces to interact with a single data source (e.g. add/edit/delete/list a SharePoint List or database table) is relatively straight-forward in PowerApps. However, moving beyond that to provide advanced interface features, including validations and integrations with Power Automate proved challenging. From the workflow perspective, the Power Automate platform offers easy ways to achieve data flow/If this then that type of workflows (e.g. extracting an attachment from an email and add to SharePoint list if the subject contains a keyword) but proved inadequate when it comes to anything but the simplest approval workflows. Perhaps the biggest shortcoming for me was that creating an app that seamlessly integrates a user interface with a workflow – where you can direct a user to activate a task from an email link – did not seem possible. This is something that is a basic feature in K2 and easy to implement.
PowerApps and Power Automate have their place in the market. In my mind, PowerApps is suited to scenarios where you want to expose data to users in an intuitive way for users to interact with on mobile devices. The UI design experience for PowerApps is a lot different than K2’s form designer, and I found it challenging to modify the form layouts. However, with some hours at the wheel, I am sure most new users would be able to get the hang of it. One major point of difference between PowerApps and K2 forms is the ability to implement your business logic via rules. In PowerApps you need to almost “code” your events with some complex formulas needed to do some basic things, whereas in K2 you have the no code rules engine that is simple and intuitive.
Power Automate is good for responding to external or internal system events (e.g. email received) and moving data around or obtaining basic approval. Once I wanted to implement anything more complex than a simple approve/decline workflow, for example, a re-work step, it was beyond my skills. I did find some examples of rework patterns, but I didn’t really have the time (or inclination!) to work on how to implement these patterns. Something like this is so simple in K2: add a “rework” action to the task and then drag your “Rework” outcome line to a “Rework Task”.
Once you move past basic app scenarios it is, of course, possible to build solutions with the PowerApps and Power Automate, but for my money, it is much simpler and intuitive using the K2 platform.