Tarator
Tarator

Reputation: 1525

Angular RX/JS Nested Observable calls

I have problems wrapping my head around how to achieve the following Problem with Reactive programming:

I want to call a Method getSearchResults(searchterm: string): Observable<Foo[]>. In this method I normally filter data from a locally stored dataset. Only if this dataset is not loaded, I want to load my dataset from the server first:

getSearchResults(searchterm: string): Observable<Foo[]> {
  if(this.dataset != null) {
    return this.filter(this.dataset, searchterm);
  }

  // Load dataset first from server. service method returns an Observable
  const obs = myService.loadDataset();
  obs.subscribe(data => {
     this.dataset = data;

     // Now I want to call filter and return an Observable
     return this.filter(this.dataset, searchterm);
  });

}

Consider this as pseudocode and no full example, but I hope it makes my problem clear. I understand, that this does not work in this manner.

But I really have a hard time to find a pattern to achieve something like this.

Any help?

Upvotes: 0

Views: 241

Answers (3)

siva636
siva636

Reputation: 16441

The following logic is simple and straightforward to achieve the goal:

localDataLoaded = false;

yourLocalDataAsObservable.pipe(
filter()
).subscribe(
data => {this.localDataLoaded = true;},
error => {},
() => {if (!localDataLoaded) {
// Load data from server, because the data you need is not in the local store
}}

)

Upvotes: 0

zhimin
zhimin

Reputation: 3050

I think you can convert observable to promise, like this:

async getSearchResults(searchterm: string): Promise<Foo[]> {
    if(this.dataset != null) {
        return await this.filter(this.dataset, searchterm). toPromise();
    }

    // Load dataset first from server. service method returns an Observable
    const data = await myService.loadDataset().toPromise();
 // Now I want to call filter and return an Observable
   return await this.filter(this.dataset, searchterm). toPromise ();
}

Upvotes: 0

Chatar Singh
Chatar Singh

Reputation: 1063

Include rxjs observable import { Observable } from 'rxjs/Observable';

And then create your own observable.

    return Observable.create(observer => {
      const obs = myService.loadDataset();
      obs.subscribe(data => {
         this.dataset = data;

         // Now I want to call filter and return an Observable
         observer.next(this.filter(this.dataset, searchterm));
      });
   });

Upvotes: 1

Related Questions