Dac0d3r Dac0d3r - 1 year ago 101
Javascript Question

How to switch between login page and app with Aurelia

I'm using the Aurelia skeleton for my project. Everything seemed so intuitive, however I'm stuck with a problem which I suspect is fairly easy (if you know how).

The problem is that the app.html / app.js is initially showing a nav bar and loading some default styles.

Now I need a login page, which does not load anything but its own styles, no navbar no nothing - just its own login form.

So I tried something like this:

app.js

<template>
<div if.bind="auth.isNotAuthenticated()">
<require from="components/login/index" ></require>
<login router.bind="router"></login>
</div>
<div if.bind="auth.isAuthenticated()">
<require from="nav-bar.html" ></require>
<require from="../styles/styles.css"></require>
<div class="container" id="banner">
<div class="row">
<img src="images/logo.png" />
</div>
</div>
<nav-bar router.bind="router"></nav-bar>
<div class="page-host">
<router-view></router-view>
</div>
</div>
</template>


Obviously that doesn't work (unless you refresh the page/f5), since the app.js / app.html is the root route which is always present and never changes. But I hope the logic within the markup helps illustrate what I'm looking to solve?

I guess my if only I knew how to reload the parent route (app.js) when I navigate from the login route, on login success, to another route. And again when I logout, the parent route (app.js) should be refreshed as well once again. Then all my problems would be solved.

What am I missing here? :-)

Answer Source

I think aurelia's setRoot(module) function will help with this.

Here's the standard main.js file that "bootstraps" the aurelia app:

main.js

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();

  aurelia.start()
    .then(a => a.setRoot()); // this is the equivalent of setRoot('app')
}

When setRoot is called with no arguments Aurelia looks for an app.js + app.html viewmodel and view.

We can adjust the logic to check whether the user is logged in and if not, show the login screen:

main.js

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();

  aurelia.start()
    .then(a => {
      if (userIsLoggedIn()) {
        a.setRoot('app');
      } else {
        a.setRoot('login');
      }
    });
}

Then in your login view model you can call setRoot('app') after the user has successfully logged in:

login.js

import {Aurelia, inject} from 'aurelia-framework';
import {AuthService} from './my-auth-service';

@inject(Aurelia, AuthService)
export class Login {
  userName = '';
  password = '';

  constructor(aurelia, authService) {
    this.aurelia = aurelia;
    this.authService = authService;
  }

  submit() {
    // attempt to login and if successful, launch the app view model.
    this.authService.login(userName, password)
      .then(() => this.aurelia.setRoot('app'));
  }
}

Note: if your app includes a "logout" feature that will send the user back to the login screen (eg setRoot('login')), be sure to reset the router and update the url accordingly. This will prevent issues when the user signs back in. More details in here and here.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download