Tersius
Tersius

Reputation: 367

RXJS Emit first result and then wait for another observable

Currently I have two observables. One returns a list of clients and the other is fired when text changes.

I would like to emit the full result of clients and then switch over to the inner observable once the user has started filtering.

I'm also trying to achieve a debounce on the text being typed.

I've put together something that doesn't work to try and explain. As it currently is it only displays clients once I start typing text.

let obs = Observable.fromPromise(this.clientService.getClients())
      .map((clients) => {
        return clients.map((c) => new Client().fromObject(c));
      });

    this.clients = obs.switchMap((values) => {
        return this.searchText.valueChanges
          .debounceTime(400)
          .distinctUntilChanged()
          .map((text) => {
            return values.filter((c) => c.isMatch(text));
          });
      });

Upvotes: 5

Views: 2595

Answers (1)

n00dl3
n00dl3

Reputation: 21564

You need to merge your observables together :

let obs = Observable.fromPromise(this.clientService.getClients())
      .map((clients) => {
        return clients.map((c) => new Client().fromObject(c));
      }).share();

let filtered = obs.switchMap((values) => {
    return this.searchText.valueChanges
        .debounceTime(400)
        .distinctUntilChanged()
        .map((text) => {
        return values.filter((c) => c.isMatch(text));
        });
    });

this.clients = Observable.merge(obs,filtered);

first you need to use the share operator to avoid fetching clients twice (see edit further). then you need to get the value from obs and also from filtered. this is what merge is made for :

Creates an output Observable which concurrently emits all values from every given input Observable.

Flattens multiple Observables together by blending their values into one Observable.

enter image description here

[source]

Edit : The share part is not necessary in this specific case as the OP is using a promise as observable source, promises not being triggered by the subscription, they are hot observables and do not need to be shared. But if you are dealing with other observable source (like angular Http service's method, you might need to share.

Upvotes: 4

Related Questions