Don't understand the timing of {{binding}} in HTML

Maybe I just need to re-read the docs and tutorials, because this is so simple - I just don’t get it though.

I have two pages in my simple app - Login and Home. If the Login succeeds, it does a nav.setRoot( HomePage ).
The Home page opens just fine. But it appears to be trying to render the HTML before it has the data to apply to the bindings, and I see an empty page!
It doesn’t matter whether I have the calls to the backend coded in the constructor() or the ionViewDidEnter() function. Since those calls are coded async using a Promise, they’re not returning in time for the data to be shown. All I see is a blank page. I built in a pull-down refresh, and THAT allows the data to be seen, but that’s a horrible UX…

Is there some trick to getting the page to wait to render the HTML until the data has been returned and is ready to bind? Or am I coding my bindings improperly? I’m just using double-bracket method… `




Hard to diagnose without code. There’s almost certainly something simple you’re doing wrong through inexperience. Changing subjects, why not just push HomePage onto the stack instead of using setRoot? Do you really want your user to be unable to return to the login page? I don’t get the UX benefit of that.

No, and you’re going to remain frustrated as long as you keep thinking in terms of “getting things to wait”. You are not in control of what happens when. You have to think reactively and defensively. In this case, that means initializing everything to sane enough defaults that the template can safely render immediately. Generally, all you need to do is someClassVariable = {};.

1 Like

I gave them a Logout button that disconnects and returns to the LoginPage and removed the Back button. I consider going “back” to the login page a poor UX… I suppose I could have used push instead of setRoot.

The way I prefer to handle this is to have authentication state stored in a service. The app component does something like this in its constructor:

authService.authenticationNotifier().subscribe((authed) => {
  if (authed) {
    this.rootPage = DashboardPage;
  } else {
    this.rootPage = LoginPage;

The authenticationNotifier is a ReplaySubject with stack depth 1. Call next(true) on it when login succeeds, call next(false) on it to logout. No need for anybody else to be interacting with the navigation system.

To close this loop - that was exactly the problem.
My Constructor event was not initializing the variable that was bound in the HTML, so when it was trying to render {{}}, it was “undefined”…
All I had to do was initialize the bound class variable to an empty JSON object, and the error went away. When the Promise that populates it with data eventually resolved, the bound property values were automatically updated.