Changes are coming to Power Apps, here’s what you should do to start moving away from App.OnStart
By now, you should have noticed that some of the things we’ve been doing are being removed or deprecated. I remember the first time I noticed this, I opened a Canvas App up to make some changes and had a red light on my App Checker. No longer was the Navigate function being allowed from the App.OnStart. Of course, this prompted me to find out what happened. I found these two little pieces of documentation from Microsoft to be very helpful:
At the time of this blog, a series of purple notes were present indicating what was changing and why. In short:
Now that we understand what happened, let’s talk about how to deal with it going forward.
First, let’s address the breaking change that no longer allows us to use Navigate in our OnStart. To deal with this, Microsoft recommends using the StartScreen property instead. When adopting this approach, we first need to understand what our application is doing.
So in the first example, we have an application that's simply called `Navigate(GalleryScreen)` at the end of the OnStart.
This is truly very easy to deal with. All we need to do is remove the `Navigate` function from the end of our OnStart property and set the `StartScreen` property to `GalleryScreen`. That’s it!
Ok, but that’s stupid simple, right? Yup, it sure is. So how do we handle situations where we need to deep-link to a form or display something to the user while we’re loading data and the primary screen isn’t ready yet?
In the case you’re deep linking to a form or can select a screen based on some piece of information that’s available “early”, we can add some logic to our `StartScreen` property. Let’s say we want to take the user directly to a filled form based on a parameter passed in the URL. We can redirect in the `StartScreen` and simply add the following bit of logic:
`If(IsBlankOrError(Param("ID")), GalleryScreen, FormScreen)`
This will detect if a record ID is being passed to our application, if it is, we’ll take the user to the form filled with the target data. If not, we’ll simply take the user to the `GalleryScreen` or our data list.
That worked as expected, but what if it takes a little time to load the data in that form? Or what if we need to do work on the data we retrieve, or it simply takes some time to retrieve it? Since we are no longer supposed to do this work in the App.OnStart, how do we deal with it?
What I have done to handle this situation is to simply introduce a dedicated “StartScreen”. I can use this screen to load my data or do any other work I might need to do to hydrate my screens. And while I’m doing that, I usually implement some sort of loading message and maybe a spinner. Remember, user experience is important, and giving the user a nice visual and clarity about what’s happening is important.
Now, let’s create our new dedicated screen. We’re going to update our `App.StartScreen` property to go directly to this new `LoadingScreen`.
Ok, now on the `LoadingScreen` we’re going to add some motion with a simple spinner gif and a loading message.
Next, we will do all that work we were talking about. In the `OnVisible` property of this new screen, we can do most, if not all, of the things we used to do in our App.OnStart. In my application, I am going to grab any parameters being passed in to handle a deep link scenario. I’m also going to preload my list data so it’s ready for the user when they show up at the `GalleryScreen`.
Now I have all the data ready. You might say, “but wait, this doesn’t work, you can’t use Navigate in the OnVisible.” And you’d be right. To take the user to the desired screen we need to use another “trigger”. That trigger is going to be a `Timer.OnEnd` property. I think there are probably a few variations on this, but I like to simply add a true/false “loaded” variable to my application. Make sure it’s `false` in the beginning, so we will add it at the top of the `OnVisible` logic.
And when we’re all done getting data, we’ll set that same variable to `true`.
Next, we’ll add a `Timer control` to our `LoadingScreen`. We will configure the timer control’s AutoStart property to the true/false variable that we just created. Set the timer’s duration to something short, like 1 second (1000ms).
And then in the timer’s `OnTimerEnd` property, we can add our logic to `Navigate`.
Putting all of that into plain English. The timer is triggered once the data is loaded and ready, then when time runs out, the user is transported to their destination.
You can also hide the timer by setting the `OnVisible` property to `false`.
Hopefully, this helps with ideas on how you can move your apps away from App.OnStart. As stated earlier, Microsoft is not done with changes related to this, be on the lookout for those. I’m particularly interested in how to make the setup of global variables and collections a bit more intuitive than doing it in the OnVisible of a StartScreen. I’ll keep you posted!