2

How can I make basic initialization of my data in app. For example if user logged in and press F5 I need to request current user data from server before all queries starts like get user order etc. In Angular 1 we have .run() directive for this case. How can I solve this problem?

frogatto
  • 28,539
  • 11
  • 83
  • 129

2 Answers2

3

There are several ways to do that:

  • You could execute some requests before bootstrapping your Angular2 application. Such first requests could rely what you save into the local / session storage.

    var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]);
    var http = injector.get(Http);
    
    http.get('/userdetails').map(res => res.json())
      .subscribe(data => {
        bootstrap(AppComponent, [
        HTTP_PROVIDERS
        provide('userDetails', { useValue: data })
      ]);
    });
    

    See this question for more details:

  • You could extend the HTTP request to transparently get these data when requests are actually executed. This would be a lazy approach.

    @Injectable()
    export class CustomHttp extends Http {
      constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, userDetailsService: UserDetailsService) {
        super(backend, defaultOptions);
      }
    
      request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        console.log('request...');
        return this.userDetailsService.getUserDetails().flatMap((userDetails) => {
          return super.request(url, options);
        });
      }
    
      get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    console.log('get...');
        return this.userDetailsService.getUserDetails().flatMap((userDetails) => {
          return super.get(url, options);
        });
      }
    }
    

    implement the UserDetailsDetails this way:

    export class UserDetailsService {
      constructor(private http:Http) {
      }
    
      getUserDetails() {
        if (this.userDetails) {
          return Observable.of(this.userDetails);
        } else {
          return this.http.get(...)
             .map(...)
             .do(data => {
               this.userDetails = data;
               // Store in local storage or session storage
             });
        }
      }
    

    and register this CustomHttp class this way:

    bootstrap(AppComponent, [HTTP_PROVIDERS,
      UserDetailsService,
      new Provider(Http, {
        useFactory: (backend: XHRBackend,
                     defaultOptions: RequestOptions,
                     userDetailsService: UserDetailsService) => new CustomHttp(backend, defaultOptions, userDetailsService),
        deps: [XHRBackend, RequestOptions, UserDetailsService]
      })
    ]);
    

    See these questions for more details:

  • Things could also be done at the level of the router outlet if you use routing. It's possible to implement a custom router-outlet that checks security / user details when a route is activated. I think that it's a little further from your need...

    See this question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
0

You could fetch the current user data before you call Angular2's bootstrap(...)

You could also fire an event (using an Observable for example) to notify other that the logged-in user is now known and initiate further requests only after this event was received.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567