Monday, June 19, 2023

Starting Your App: Splash Screen vs. OnStart

Microsoft revamped how they handle the OnStart event for PowerApps last year (2022) and they made some additional tweaks this spring.  This has led some people to messing around w/ an array of methods using OnStart and StartScreen and just causing themselves no end of headaches.  Ultimately, there is one way you should start your application, and that is with a Splash Screen that does all of this in one place.

Why Is Microsoft Messing with us?

I'm old enough to remember quite clearly the days of Autoexec.bat and Config.sys (which includes still retaining far too much knowledge around EMM386).  OnStart is similar to that situation in that once Windows took over, Microsoft kept trying to stop us from using these tools because it made them look bad.  Our crappy configurations that slowed down the machine or broke things all fell on their shoulders, and they don't like that.

What Microsoft wants is for the end-user to get into their application very quickly so that the metrics all look glorious from their perspective.  The apps started, first screen loaded, and whatever nonsense we put in there from that point on is on us and not them.

What this means is that Microsoft isn't done messing around w/ those starting methods, and it is best that we just get out of their sandbox and get things stable for our own applications.  As well, it is probably better practice to let our users know if we're going to be loading a bunch of garbage at start and displaying those steps on screen during a Splash Screen is better than just making them wait in limbo with no information.

Setting things up

First off, we won't use the  OnStart and StartScreen for any logic.  Virtually everything you did in these will be instead executed from a button you will create on your Splash Screen.

Secondly, create a "Splash Screen" and put that at the top of your application screen listing.

The top screen loads first by default

On your splash screen you will include whatever information you want your end-user to see as things are "booting up" including your application name, some status information, version, etc.  However, there are only three key things you need to do so things will run properly.

  • IMPORTANT!  Create a Boolean variable that indicates if your automatic startup logic should run or not (you can do this on a non-displayed Admin page)
  • Create a button on your Splash screen that will hold all of the startup logic
  • Have the OnVisible property for the Splash Screen check to above Boolean before selecting the button that contains your automation
For now, simply create the Splash Screen and some basic fields.  We'll come back to it later.



Automation Boolean

Do not skip this step.  You've been warned.

Once we have everything set up, our Splash screen will ALWAYS wind up navigating away if you try to view it (even when editing), so we need to have a boolean that indicates if we want our automation to run or not.  This can be easily done by creating a button on some non-user Admin page that isn't visible to the end-user and sets things up.  I suggest the following configuration for this button:

OnSelect

Set(
    pauseAutomation,
    !pauseAutomation
);
Navigate(yourSplashScnName)

Text

If(
   pauseAutomation,
   "Un-pause Automation", 
   "Pause Automation"
)

What this gives you is a button that will flip the True/False value of the Boolean pauseAutomation when the button is pressed.  It also will tell if your automation is paused/running at a glance.  Finally, it will push you directly to the Splash page which is probably where you want to go if/when you pause things.

Splash Screen

Now we can get back to the Splash Screen created above.  We will:

  • Create a button for the starting logic
  • Set the Visible property for the button to be simply pauseAutomation
  • Have the OnVisible for the page Select() that button if the pauseAutomation Boolean = true
  • Put our starting logic into the button's OnSelect

Go ahead and create a button on the Splash Screen if you haven't already.  Set the Visible property to be pauseAutomation.  What will happen here is that your button will likely disappear since all Booleans are false by default.  Until we go back and click on the button you created in the step above it won't display.  Go back to that screen and click the button.  Note the change in text on the button which should now say "Un-pause Automation".  Go back to your Splash Screen and the new starting logic button should re-appear.

Next, edit your OnVisible property for the Splash Screen itself.  Change the code to the following:

If(
    !pauseAutomation,
    Select(yourStartingLogicBtnName)
)

What this does for us is that now if we Navigate to our Splash Screen while we're editing, it will not auto-select the button, but for any end-user, it will always select the button.  Again, Booleans are always FALSE by default.  So for all situations, the above code will be TRUE when an end-user runs the app, but we can switch between TRUE/FALSE when editing by using the original button at the start.

Finally, now you can edit the OnSelect for your starting logic button to be everything you'd have normally done during your App | OnStart followed by a Navigate() command at the end to go to whatever screen the end-user should see.  

Set(
    appVersion,
    1.0
);
Set(
    currentUserEmail,
    User().Email
);
.
.
.
Navigate(mainScn);

Other Ideas

I generally include a Status field on my screen to show what's going on for the end user.  So if we are loading a bunch of data at the startup, then I try to communicate that.

I would suggest a text field that displays the value of a variable that you update as your app rolls through the various starting tasks it completes.  For example:

UpdateContext({statusMsg:"Checking Version"});
.
.
.
UpdateContext({statusMsg:"Loading User Preferences"});
.
.
.
UpdateContext({statusMsg:"Loading Locations"});

Between each of the status changes, simply do the logic you normally would do between them.  While you could do some of these loads simultaneously in tandem, it helps in most cases to let the end-users understand what is going on as that can also help in troubleshooting.


Why did I Need That Stupid Boolean?!

This is one of those mistakes you probably will only make once.  Or at least, it should be painful enough that you shouldn't do it again.

If you just ignore my first step and just right to making your OnVisible for the Splash Screen immediately run the Button you create, then you've set yourself up for a scenario where you cannot edit your splash screen.  What this means, is that if you try to look at that screen even when editing, it will immediately push you to the next screen.  You'll never be able to edit this code.  

Your first option at that point will be to attempt to quickly click on things like the OnVisible selection from the upper left-hand drop-down before the button executes/navigates (which could be a problem if you haven't done anything other than just have it navigate) and delete the code calling the button.  However, this doesn't work in all scenarios and likely will simply execute too quickly.

As a second option you can try to move your Splash Screen down and create a new one at the top.  Then you can perhaps do a copy/paste of the button from the original screen (but again you'll need to move quickly) to salvage your startup code.

If the code is still executing too quickly, then you can of course try to edit any Power Automate scripts you might be calling to put in a delay to buy yourself some time.  Or doing something funky w/ your datasource(s) you might be querying to slow things down.  Or ultimately, just start re-coding it and remind yourself not to forget the pauseAutomate Boolean.

Again, you won't make this mistake twice.  If you do, then consider tattooing it upside-down on your forearm so you can read it while typing.

Final Thoughts

I know that the above series of steps can appear a little convoluted.  It's a little hack-y.  However, a Splash Screen is probably something you *should* be doing anyway.  Something to let the end user know they're where they are supposed to be.  As well, not just loading a bunch of data for 30 seconds before an end-user can touch anything is a terrible approach.  So doing that work once we hit a screen is good from a User Experience perspective.

Since Microsoft is not done modifying some of the startup logic within applications, taking your code out of their hands and doing things a little more manually is probably the safest choice you can make here.  Many people's applications broke this spring when the forced push to the latest PowerApps engine caused the OnStart code to not execute and complete before it got to the first screen.  Who can say what the next optimization will be?

While this is annoying, it is fairly easy to create a template from this and load this in as a starting point for any new app you create, so there are fairly good odds you'll only have to do this once.

No comments:

Post a Comment

Because some d-bag is throwing 'bot posts at my blog I've turned on full Moderation. If your comment doesn't show up immediately then that's why.

DIAF Visualpath team