Ilya Chernomordik Ilya Chernomordik - 1 month ago 9
TypeScript Question

Is it possible to update Observable with own data in Angular2 / Typescript?

I have an ngFor with async like that:

<div *ngFor="let location of googleSearchLocations | async">
<div *ngFor="let location of facebookSearchLocations | async">


and this is my component:

private searchTerms = new Subject<string>();
googleSearchLocations: Observable<GoogleLocation[]>;
facebookSearchLocations: Observable<FacebookLocation[]>;

ngOnInit(): void {

this.googleSearchLocations = this.searchTerms
.debounceTime(300)
.switchMap(term => term
? this.locationService.getGoogleLocations(term)
: Observable.of<GoogleLocation[]>([]));

this.facebookSearchLocations = this.searchTerms
.debounceTime(300)
.switchMap(term => term
? this.locationService.getFacebookLocations(term)
: Observable.of<FacebookLocation[]>([]));
}

search(term: string): void {
this.searchTerms.next(term);
}


To populate both arrays I use
search
method with a value from the input.

Now at some point I wanted to hide the divs by just assigning an empty array which will hide the data (like in non-async case). But it appeared to be more complex than I thought, since assigning null or new Observable breaks future updates. So is there a way to somehow do "next" or send some data to observable directly (an empty array in my case)?

I know I can just push it to the
searchTerms
, but is not desired since it will hide both divs at the same time + it will use the debounce value.

Answer

You could do the following. You keep your code but merge the subject into it. This would look like this:

let subject = new Subject();

this.googleSearchLocations = this.searchTerms
                                 .debounceTime(300)
                                 .switchMap(term => term 
                                     ? this.locationService.getGoogleLocations(term)
                                     : Observable.of<GoogleLocation[]>([]))
                                 .merge(subject);

If you know want to clear the list. You could just do

subject.next([]);

This doesn't mess with the original searchTerms stream and allows you to clear the result immediately and only for one of the two.

You can provide two different subject for the two (google and facebook) so you could clear them both separately at your time of choosing.

Jsbin with a similar example can be found here: http://jsbin.com/pagilab/edit?js,console

It first emulates result being found and clears the result with an empty array after 2seconds.