Angular 2 call service only on app initialization

谁说我不能喝 提交于 2019-12-10 16:02:48

问题


What I am trying to accomplish is to call external API only once per app initialization.

I have a simple service,

@Injectable()
export class XService {
    url = "http://api.example.com"
    constructor(private _http:Http) {

    }

    callAnAPI(){
        console.log('made an external request");
        return this._http.get(url)
            .map(res=>res.json());
    }
}

and two components, the main appComponent

@Component({
  selector: 'my-app',
  template: `
    <div>
      Test
    </div>
  `
})

export class AppComponent {
    isLoading = true;
    results = [];

    constructor(private _service: XService){

    }

    ngOnInit(){
        Observable.forkJoin(
            this._service.callAnAPI()
            // some more services here
        )
        .subscribe(
            res => {
                this.results = res[0];
            },
            null,
            () => {this.isLoading = false}
        );
    }
}

and another component used with a route

@Component({
  template: `
    <div>
      I want to use the service with this component.
    </div>
  `
})

export class SecondComponent {

    constructor(private _service: XService){

    }
}

the service is initialized and Angular hits server on the initialization of the AppComponent. I want to Use XService with SecondComponent too, whenever I try to call the service again from the SecondComponent, (via _service._service.callAnAPI()) Angular hits the external API. I want to minimize the external hits.

How do I obtain the data made by the AppComponent on initialization than calling again the service again in SecondComponent


回答1:


You could use the do operator for this to get the data the first time and reuse them for next calls:

@Injectable()
export class XService {
  url = "http://api.example.com"
  constructor(private _http:Http) {

  }

  callAnAPI(){
    console.log('made an external request");
    if (this.cachedData) {
      return Observable.of(this.cachedData);
    } else {
      return this._http.get(url)
        .map(res=>res.json())
        .do((data) => {
          this.cachedData = data;
        });
    }
  }
}

If you want to load data as startup, you can call the callAnAPI method from the service constructor.

To be able to use this approach, you need to define your service when bootstrapping your application:

bootstrap(AppComponent, [ XService ]);

This way you will use a single instance for your whole application.




回答2:


@Injectable()
export class XService {
    url = "http://api.example.com"
    constructor(private _http:Http) {

    }

    callAnAPI(){
      if(this.data) {
        return Observable.of(this.data);
      } else {
        console.log('made an external request");
        return this._http.get(url)
            .map(res=>res.json())
            .do(res => this.data = res);
      }
    }
}


来源:https://stackoverflow.com/questions/36083114/angular-2-call-service-only-on-app-initialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!