Catch nav guards during tab navigation

I have a tabbed view that has at least two tabs: account and favorites.

The account view has links to the Login page, and the favorites page displays a login form for logged out users that can also log users in. The Login page has a guard, ionViewCanEnter that returns false if the user is logged in.

If you navigate to the Login page and then select the Favorites tab, log in, and then select the Accounts tab, the app will crash because the navigation to the Account tab keeps getting rejected because of the guard.

There are two possible solutions that I can see:

  1. After successful login on the favorites tab, reset the account tab to the Account page instead of the Login page.
  • There doesn’t seem to be a way to change the navigation of a different tab from the current tab.
  1. Catch the navigation error caused by the guard when navigating tabs and set the Account page for the account tab accordingly.

Is there any way to do either of the above?

This seems like a confusing design to me. One of my UI rules is “don’t provide a way for users to do things I don’t want them to do”, so I would do away with the guard and simply not show any elements that would attempt to log in if you don’t want that happening.

I also think it’s confusing to have all these login forms all over the place.

If you want to support guest users, then have the Account page be a chimera of user preferences (if logged in) or a login form (if not). That way there is no concept of “the Login page”, no guard needed, and no problem.

If you don’t need to support guests, then merely switch the top-level rootPage to either DashboardPage (tab container) or LoginPage depending on login status. If you search the forums for logout user:rapropos, you will probably find a bunch of posts like this one containing sample code for how I handle user authentication.

I have no (final) control over the design of the app, but I do agree with some of the things you said from a design perspective.

The Account page does not have the login form, it’s a page you can get to from within the account tab. The landing page just has some links like “Help,” and if you are logged in it will show some profile information.

I could just remove the guard and when the user enters the login page it can do a navCtrl.pop if they are logged in. I would just like to be able to use the guard and not show the page at all if I can.

Well, hopefully you can convince whoever does that its UX can be improved.

IMHO this is abuse of tabs. Tabs should only have one consistent child. I’m saying that profile information isn’t a meaningful concept if the user is not logged in, so why not reuse its space for the login form in that situation? The “Help” link could be present in both cases:

<a>help</a>
<form *ngIf="!authed">
login form
</form>
<div *ngIf="authed">
profile stuff
</div>

You could conditionally change the name of the tab from Account to Login if you think that’s important.

If I’m a user, “Account” seems like a sensible place for me to do account-y stuff, like signing up or logging in. “Favorites” emphatically does not. In fact, if I am not logged in, I would find the very presence of a “Favorites” tab (that’s not disabled) baffling. I certainly would not expect that selecting it would give me a login form.

This is a retail app. If you are not logged in the Favorites page is a page saying “You can have favorites, but you have to be logged in, please log in below” (includes a login form to reduce friction to the user, I suppose).

As for the Account page, The !authed page has two buttons: Create Account / Log In which is why it doesn’t display the login form immediately. I could also change this to be one page that displays the login form conditionally if you press the “Log In” button, but it makes sense to me to use navigation and have this as a separate page – especially since the log in page is used in another spot, i.e. during checkout.

As for each tab having only one consistent child, that’s not good news for us since we also have a “Shop” tab (not relevant here since functionality doesn’t depend on Auth) that you can drill down to quite a bit to find product lists in different categories, specific product information, etc.

I’m starting to question whether tabs are a good fit for this app. It seems like the “shop” page would make more sense for the landing page, as 80-90% of a user’s time would generally be spent with it. Tabs, in my experience, work best for situations where you expect users to spend roughly the same amount of time in each tab’s “realm”. When one realm is clearly dominant, users tend to prefer having that dominant page be the default, and resent screen real estate (and attention) being taken up by tabs representing stuff they only deal with rarely.

Favorites and account statistics can be icons in the navbar or a side menu, and if you’re doing login as a modal at checkout in one place, why not just pop that same login modal from anywhere (again via an icon button or menu item)? Saves you having two separate login forms, and makes the UI more consistent as well.