0
votes

I have declared the data I want from the API using observable in a separate class. I want to access the data declared in the separate class into my component class. But javascript being asynchronous in nature will give me undefined once the control crosses the function call of the observable method. So is there a way to 'subscribe' to this function that already contains an observable that is fetching data or any other way of accessing data from getData() in GetDataClass.ts into my Component class?

Here's the code: GetDataClass.ts

  Data: any;
  getData() {
          this.dataservice.getAllData()
               .subscribe(response => {
                    this.temp = response;
                    this.Data = this.temp.ReturnData.DataList;
                    console.log('this.data new: ', this.Data);
               }, err => console.log('error: ', err))
     }

AppComponent:

data: any;
constructor(private dataService: GetDataClass ...){
    this.dataService.getData();
    this.data = this.dataService.temp
}

}

2

2 Answers

1
votes

I am assuming that you wish to "share" the observable values as you wouldn't want to make multiple requests to the server side for the same set of data.

There are multiple RxJS operators you can make use of, such publishReplay() and shareReplay().

For instance, in your dataservice, we can modify getData to make use of publishReplay() to fire the cached values.

import { publishReplay, refCount } from 'rxjs/operators';

getData() {
  return this.http.get(`api-request`)
    .pipe(
      publishReplay(1),
      refCount()
    );
}

Similarly, we could make use of shareReplay.

import { shareReplay } from 'rxjs/operators';

getData() {
  return this.http.get(`api-request`)
    .pipe(
      shareReplay({refCount: true, bufferSize: 1})
    );
}

On your AppComponent class, you can subscribe to getData() as per usual, yet avoiding multiple requests to the same endpoint.

res: any;

ngOnInit(){
  this.dataService.getData().subscribe(data => {
    this.res = data;
  });
}
0
votes

Assuming you have class A which gets the data and class B which consumes the data, you could to the following:

  • create a subject in A so that every time new data comes in, you can can emit the data. You also need to expose this subject as a public observable, so other consumers can get notified when data comes in:
// `A` class
private _data$ = new Subject();
data$ = this._data$.asObservable();

getData () {
 this.apiService.get(...)
   .subscribe(results => {
    this._data$.next(results);
 })
}
  • create a consumer of class A. In this case, it will be called class B. Here you would import the class A and subscribe to the observable it exposes:
// `B` class

constructor (private aService: AService) { }

ngOnInit () {
 this.aService.getData();

 // Subscribe so you can get the new data every time
 this.aService.data$
  .subscribe(data => {
   // Do something with the data..
 })
}