1

Right now in my Angular 2 app I am handling logging in and logging out successfully. I'am also using ActivatedRoute and queryParams to re-load all the last loaded components upon the event of the user logging out, and then logging back in, all within the same session. The login component looks like this:

ngOnInit()
{
    // reset login status
    this.authenticationService.logout();

    // get return url from route parameters or default to '/'
    this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}

login(response)
{
    this.loading = true;
    this.authenticationService.login(this.model.username, this.model.password)
        .subscribe(
            data =>
            {
                this.router.navigate(['returnUrl']);
                this.reset();
            },
            error =>
            {
                this.alertService.error(error, response);
                this.loading = false;
            });
    this.authenticationService.username = this.model.username;
}

The only tweak I'd like to handle is, if there were three tabs/components loaded, when the user logs out and then logs back in, I'd like to load the last active tab as the new active tab.

Right now we're using a AuthGuard and a redirect in our app-routing file to redirect to the dashboard component in all cases after login has happened successfully. So this handles both situations where the user enters an unknown route, and when the user first logs in, or logs in again within the same session. The app-routing file looks like this:

{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard], data: {contentId: 'dashboard'} },

{ path: 'about', component: AboutComponent, canActivate: [AuthGuard], data: {contentId: 'about'} },

{ path: 'login', component: LoginComponent },

{ path: '**', redirectTo: 'dashboard' }

And here's the relevant code from my authenticationService:

login(username: string, password: string)
{
    const u = encodeURIComponent(username);
    const p = encodeURIComponent(password);
    return this.http.post(this.url + this.ver + '/' + 'customers/login/' + u + '/' + p + '?' + this.key, {})
        .map((response: Response) =>
        {
            // login successfully if there's a 200 response
            const user = response.json();
            // if (user && user.token) {
            if (user && (response.status = 200))
            {
                localStorage.setItem('currentUser', JSON.stringify(user));
                console.log('User ' + this.username + ' successfully authenticated with API');

                // Track active user id
                this._userId = user.data._id;

                // Trigger login change
                this.change.emit(this);
            } else
            {
                console.log('User ' + this.username + ' not recognized by API');
            }
        });
}

isAuthenticated()
{
    if (localStorage.getItem('currentUser'))
    {
        return true;
    } else
    {
        return false;
    }
}

logout()
{
    // remove user from local storage to log user out
    localStorage.removeItem('currentUser');
    console.log('User successfully logged out');

    // Reset active user
    this._userId = undefined;

    // Trigger event
    this.change.emit(this);
}

My AuthGuard file looks like this:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
{
    // Get route content id
    let contentId = Object.getPropertyValueAtPath(route, 'data.contentId');

    //If route does not have session id, don’t load in tab view
    if (!String.isNotNullOrEmpty(contentId))
    {
        console.error(`Route (${route.routeConfig.path}) does not have a content id.`);
        this.router.navigateByUrl(''); // Forward to default page.
        return false;
    }

    if (this.disabled)return true;

    if (localStorage.getItem('currentUser'))
    {
        // logged in so return true
        return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login', {returnUrl: state.url}]);
    return false;
}

But what I'd like to do is load the last active tab/component, rather than simply loading the dashboard component each time. How would I handle that kind of desired behavior? Does routing within Angular allow me set a set a conditional clause here, instead of always defaulting to the loading of one default component?

It also occurs to me that a way I could perhaps do this is to make note of the full url path just before logging out, via window.location.pathname. And then I would need to pass that value back in on the login() function. Still trying to figure out how to do that while also getting all open tabs/components via: this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';

Muirik
  • 6,049
  • 7
  • 58
  • 116

0 Answers0