0

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?

3 Answers 3

1

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));
      });
   });
Sign up to request clarification or add additional context in comments.

4 Comments

This is exactly what I was looking for five hours now! Thank you very much!
it triggers myService.loadDataset() on each subscription for result observable, isn't it?
yes, it does, but for that i check with an if if data is already loaded... Meaning: I only create this Observable if the data hasn't been loaded already...)
hm, okay. other issue there - you loose complete/error which can be emitted by data set observable. as you delegate only observer.next invocation in subscribe
0

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 ();
}

Comments

0

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
}}

)

Comments

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.