简体   繁体   中英

Angular fetch JSON Object from API and store it in variable, check if existing

I'am working on an Angular Project and I have a Problem which I didn't mange to solve...

//part of class Data
constructor(private fetchData: FetchData) {
  this.subscription = timer(0, 1000000).pipe(
        switchMap(() => this.fetchData.getData())
    ).subscribe((result) => this.data = result);
}

private data: any;
private subscription: Subscription;

public getData(): Object {
    return this.data.data_property;
}

It reports errors because of a runtime condition and I want to solve this Problem by waiting for the variable to be filled. The whole app needs it, so it is pretty important. I want to solve it with an Observable from Angulars rxjs but I didn't really got it to work, I'am pretty new to this. By the way, both, the FetchData and the Data Class are @Injectable Services.

If somebody has an additional Tip for me to convert the variable data to a type of Interface eg "myData" I would be very happy, too, because I don't want to use the hack with any. Problem is the getData of FetchData returns just an Object from HttpClient:

//part of class FetchData
getData() {
    return this.http.get(this.dataUrl)
    .pipe(
        catchError(this.handleError)
      );
}  

Tanks for helping anyways. Love Stackoverflow community :D

Main problem

  1. If you need load some data before app is loaded app_initializer can be used Angular: How to correctly implement APP_INITIALIZER
  2. Maybe in this snipped a reference to a class field this.data should be used instead of class Data itself
public getData(): Object {
    return this.data.data_property;
}

Response type
Http methods let you provide a generic, like this this.http.get<CustomResponseInterface>()

One of the approaches could be the following -

Have your data service setup like this -

  export class DataService {

  //This is
  private _data$: BehaviorSubject<any> = new BehaviorSubject<any>(null);

  data$: Observable<any>;

  constructor(private fetchData: FetchData) {
    this.data$ = this._data$.pipe(filter(d => !!d));
    this.getData();
   }      

  getData() {

    timer(0, 1000000).pipe(
      switchMap(() => this.fetchData.getData()),
      tap(d => {
        this._data$.next(d);
      })
    ).subscribe();
  }
}

Now to make use of the DataService.data$ do the following in the component [In this example I am assuming it is HomeComponent] where you want to use the fetched data [you can use data$ observable in as many component/services as you want, it will emit last fetched data from the backend] -

export class HomeComponent implements OnInit {

  constructor(private dataService: DataService) { }

  data$: Observable<any>;

  ngOnInit() {
    this.data$ = this.dataService.data$;
  }    
}

in html of HomeComponent

<div *ngIf="data$ | async as data">
  <!-- Render your 'data' -->
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM