8

I want to reload my Angular 2 app after a user clicks a logout button, that is I want to clean all current data in the app and to load a sign in form from the server.

Now, after clicking a logout button, I am getting the answer from the server (with sign in form in it) in my subscribe method, but I do not know how to clean current app's data and to load sign in form.

Can anybody help me?

This is my main class AppComponent

import {Component}          from 'angular2/core';
import {OnInit}             from "angular2/core";
import {Router}             from "angular2/router";
import {RouteConfig}        from "angular2/router";
import {AuthRouteOutlet}    from "./common/directives/auth-router-outlet.directive";
import {AuthService}        from "./common/services/auth.service";
import {DashboardComponent} from "./common/components/dashboard.component";

@Component({
  selector: 'my-app',
  template: `
    <auth-router-outlet></auth-router-outlet>
  `,
  directives: [AuthRouteOutlet, DashboardComponent]
})
@RouteConfig([
  {path: '/dashboard/...', name: 'Dashboard', component: DashboardComponent, useAsDefault: true}

])
export class AppComponent implements OnInit {
  constructor(
      private _router: Router,
      private _authService: AuthService
  ) {}

  ngOnInit():any {
    var self = this;

    this._authService.getLoggedOutEvent().subscribe(function(next) {
      //console.log('AppComponent OnEmit: ' + JSON.stringify(next));
      self._router.navigateByUrl('/', true);
    });
  }
}

This is my service. I send the logout request from here.

import {Injectable, EventEmitter} from 'angular2/core';
import {User} from "../models/user.interface";
import {Http} from "angular2/http";
import {Observable} from "rxjs/Observable";
import {Headers} from "angular2/http";

@Injectable()
export class AuthService {

  private _userLoggedOut = new EventEmitter<any>();

  constructor(private _http: Http) {}

  getLoggedOutEvent(): EventEmitter<any> {
      return this._userLoggedOut;
  }

  logout(): Observable<any>{
    return this._http.get('/logout');
  }
}

And this is my component from which I invoke the logout method.

import {Component}    from "angular2/core";
import {ROUTER_DIRECTIVES, Router} from "angular2/router";
import {AuthService}  from "../services/auth.service";

@Component({
  selector: 'mdm-header-bar',
  template: `
    <header>
      <nav id="mdm-header-bar" >
        <ul>
          <li><a (click)="addComponent()" title="Add component"><i class="fa fa-plus-circle"></i></a></li>
          <li><a (click)="settings()" title="Settings"><i class="fa fa-cog"></i></a></li>
          <li><a (click)="help()" title="Help"><i class="fa fa-question-circle"></i></a></li>
          <li><a (click)="logout()" title="Logout"><i class="fa fa-sign-out"></i></a></li>
        </ul>
      </nav>
    </header>
  `,
  directives: [ROUTER_DIRECTIVES]
})
export class HeaderComponent {
  constructor(private _authService: AuthService) {}

  logout() {
    var self = this;
    this._authService.logout()
        .subscribe(function(next) {
          self._authService.getLoggedOutEvent().emit(next);
        }, function(exception){
          console.log('HeaderComponent OnException: ' + exception);
        }, function() {
          console.log('HeaderComponent OnCompleted ');
        });
  }

}

When I load app's main page the first time (I send the request to localhost:3000), the server checks if I authenticated and if not, it redirects me to the localhost:3000/signin page. After authentication the server sends me the main page: localhost:3000

When I send the logout request, the server logouts me and sends back an answer with localhost:3000/signin page, because I am not logged in already.

I get this page from the server in my logout(...).subscribe(...) method, but I do not know how to unload the current page (app) and get browser to load this page.

Alexander
  • 169
  • 1
  • 1
  • 9
  • Well, this is not easy question. It depends how your code has been written. Could you add some snippets? Additionally check this blog post https://auth0.com/docs/client-platforms/angular2 – ssuperczynski Apr 02 '16 at 15:40
  • What effect do you expect from reload? Why would you want to do that? Why not change the route? – Günter Zöchbauer Apr 02 '16 at 16:37
  • @ssuperczynski Thank you ssuperczynski. I'll sertanly check. – Alexander Apr 02 '16 at 18:28
  • @GünterZöchbauer I expect the app to clear all data which current user has worked with and browser to load signin page. Because in my scenario the user has finished his work with the app and I need to close his session and set the app to initial state. I tryed to change route, but it doesn't change. Sertanly, I do something wrong, but I don't know what it is. – Alexander Apr 02 '16 at 18:36

3 Answers3

7

Thank everybody for trying to help me. It's very kind of you.

@GünterZöchbauer, thank you very much. Your third link:

The approach shown in How to reload a page using Javascript? should also work but is not WebWorker safe.

gave me the right answer. I changed my logout() method to:

logout(){
    window.location.replace('/logout');
  }

instead of:

logout(): Observable<any>{
    return this._http.get('/logout');
  }

and now my app works correctly.

Thank you very much.

Alexander
  • 169
  • 1
  • 1
  • 9
3

update

.dispose() is destroy() since beta.16

original

I haven't tried this myself but the solution mentioned in https://github.com/angular/angular/issues/7009 sounds promising

@rizwanhussain-vteams to reset the app you can save ComponentRef instance which is resolved by promise that bootstrap returns.

var appRef;
bootstrap(App).then((_appRef) => {
  appRef = _appRef;
});

So you can call dispose method of ComponentRef instance (appRef) to destroy component and then you can bootstrap it again.

This discussion might also be interesting https://github.com/angular/angular/issues/7429

The approach shown in How to reload a page using JavaScript? should also work but is not WebWorker safe.

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Could you explain bit more about `this.location.reload();` – Pardeep Jain Apr 03 '16 at 09:11
  • @PardeepJain Ouch! The [Location](https://github.com/angular/angular/blob/master/modules/angular2/src/router/location/location.ts) class doesn't have a `reload()` method. No idea where I got it from back then and why it is confirmed to work. Have to investigate more. – Günter Zöchbauer Apr 03 '16 at 09:21
  • 1
    I removed it, because I couldn't anything that confirms this to be working. Thanks a lot for you comment! – Günter Zöchbauer Apr 03 '16 at 09:33
0

I found that the following post was useful and confirm it works up to Angular 8 beta 10

Resetting Angular 2 App

What is useful to do is to make an actual login screen because re-bootstrapping the application makes a logout() button freeze for a few seconds.

Piotr Stulinski
  • 9,241
  • 8
  • 31
  • 46