0

I would like to make a web API call as soon as my app starts. This Http call should return an array of Json objects.

I want to create HTML elements (in my root app) depending on how many elements were returned and then access and display that data in different (child->child->child) components without grinding it down to all those childs from the root app.

I guess I have to create a service class.

Questions

  1. Is a service instantiated as soon as the app is started or only when the first component is getting created that uses that service?
  2. Can I use a promise to achieve my desired behavior or do I have to use observable (BehaviorSubject)?
  3. According to 2. Is it possible to start a web API call (as soon as app starts) and then check from other indepentend components if the data already exists in my service and use it?
3
  • 1
    Personally I used ngOnInit() { this.getNames() } to return a list of users and then <ul><li>*ngFor="let name of names"</li></ul> to dynamically create a list element for each name returned. I'm not sure if that is of use to you directly but maybe it will be. Commented Jul 14, 2017 at 11:34
  • The problem with this approach is, that I have nested components in (your example given) the li elements and I dont want to grind the data like name all the way through my container and other components until I reach a component where I need it Commented Jul 14, 2017 at 12:32
  • 1
    check this answer Commented Jul 14, 2017 at 13:31

1 Answer 1

0

You can use APP_INITIALIZER to call the HTTP method on startup, like described in this question.

If you go this route - if you use promise, the app won't load until the JSON is downloaded, if you use observable, it will start downloading on startup and continue rendering everything else.

If you store the returned values in a field of the service you can access them from everywhere.

Some code: app.module.ts

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { Http, HttpModule, JsonpModule } from '@angular/http';
import { UserService } from '../services/user.service';

<...>
@NgModule({
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule,
    JsonpModule,
    routing
  ],
  declarations: [
    AppComponent,
    <...>
  ],
  providers: [
    <...>
    UserService,
    {provide: APP_INITIALIZER,
      useFactory: (userServ: UserService) => () => userServ.getUser(),
      deps: [UserService, Http],
      multi: true
    }
  ],
  bootstrap: [AppComponent]

user.service.ts

@Injectable()
export class UserService {

    public user: User;
    constructor(private http: Http) { }

    getUser(): Promise<User> {
        console.log('get user called');
        var promise = this.http.get('/auth/getuser', { headers: getHeaders() })
            .map(extractData)
            .toPromise();
        promise.then(user => {
            this.user = user;
            console.log(this.user);
        });
        return promise;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

1. I have read that the APP_INITIALIZER is still experimental and this is used in an app for our customer. 2. How do I know when the field in the service has my desired data from the web call? Because the app will defenitely render faster than the web call returns my data.
1. It's not experimental anymore angular.io/api/core/APP_INITIALIZER 2. try a simple ngIf in the template or if that won't work or if you dont want to output from service directly to template, make an observable and broadcast that the data was loaded like here stackoverflow.com/documentation/angular2/7400/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.