Pass an observable off to the HTML

master
Matt Huntington 9 years ago
parent 27da0a7c2a
commit 53eea259d2

@ -10,6 +10,7 @@
1. Check for distinct events from an observable 1. Check for distinct events from an observable
1. Create a service for an observable 1. Create a service for an observable
1. Format the content of the event being published 1. Format the content of the event being published
1. Pass an observable off to the HTML
## Describe publish/subscribe model and how it relates to Observables ## Describe publish/subscribe model and how it relates to Observables
@ -310,3 +311,80 @@ Back in `src/app/search/search.component.ts` we can simplify what comes back fro
this.searchService.createAPIObservable(name) this.searchService.createAPIObservable(name)
.subscribe(results => this.results = results); .subscribe(results => this.results = results);
``` ```
## Pass an observable off to the HTML
We can operate on an observable in the HTML. This cleans up our code a bit. First add `switchMap` functionality to `src/app/search/search.component.ts`:
```javascript
import 'rxjs/add/operator/switchMap';
```
Now change subscribe to switchMap.
```javascript
this.searchSubject
.debounceTime(300)
.distinctUntilChanged()
.switchMap(name => this.searchService.createAPIObservable(name))
.subscribe(results => this.results = results);
```
`.subscribe(results => this.results = results)` is actually subscribing to the observable created by `searchService`, NOT `searchSubject`. It may look like it's subscribing to `this.searchSubject`, but it's not. It's essentially mapping any event published by `searchSubject` to the one created by `this.searchService.createAPIObservable()`.
Lastly, we can remove the `.subscribe()` code altogether and set `this.results` to the observable returned by the rest of the statement:
```javascript
ngOnInit() {
this.results = this.searchSubject
.debounceTime(300)
.distinctUntilChanged()
.switchMap(name => this.searchService.createAPIObservable(name));
}
```
Now change the HTML in `src/app/search/search.component.html` to handle the fact that `this.results` is actually an observable.
```html
<li *ngFor="let character of results | async">
```
This should work. Let's clean up our names so it's clear. Edit `src/app/search/search.component.ts`:
```javascript
export class SearchComponent implements OnInit {
apiObservable; //used to be results
searchSubject = new Subject();
constructor(
private http: Http,
private searchService: SearchService
) { }
findCharacter(name){
this.searchSubject.next(name);
}
ngOnInit() {
//this.results = this.apiObservable
this.apiObservable = this.searchSubject
.debounceTime(300)
.distinctUntilChanged()
.switchMap(name => this.searchService.createAPIObservable(name));
}
}
```
Now edit `src/app/search/search.component.html`:
```html
<section *ngIf="apiObservable">
```
and:
```html
<li *ngFor="let character of apiObservable | async">
```

@ -2,10 +2,10 @@
<h2>Search For A Star Wars Character</h2> <h2>Search For A Star Wars Character</h2>
<input [(ngModel)]="name" type="text" placeholder="Character Name" (keyup)="findCharacter(name)" /> <input [(ngModel)]="name" type="text" placeholder="Character Name" (keyup)="findCharacter(name)" />
</section> </section>
<section *ngIf="results"> <section *ngIf="apiObservable">
<h2>Search Results</h2> <h2>Search Results</h2>
<ul> <ul>
<li *ngFor="let character of results"> <li *ngFor="let character of apiObservable | async">
<h3>{{character.name}}</h3> <h3>{{character.name}}</h3>
<dl> <dl>
<dt>Birth Year</dt> <dt>Birth Year</dt>

@ -4,6 +4,7 @@ import { Http } from '@angular/http';
import { Subject } from 'rxjs/Subject' import { Subject } from 'rxjs/Subject'
import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged'; import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/switchMap';
import { SearchService } from './search.service' import { SearchService } from './search.service'
@ -14,7 +15,7 @@ import { SearchService } from './search.service'
}) })
export class SearchComponent implements OnInit { export class SearchComponent implements OnInit {
results; apiObservable;
searchSubject = new Subject(); searchSubject = new Subject();
constructor( constructor(
@ -27,13 +28,10 @@ export class SearchComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
this.searchSubject this.apiObservable = this.searchSubject
.debounceTime(300) .debounceTime(300)
.distinctUntilChanged() .distinctUntilChanged()
.subscribe(name => { .switchMap(name => this.searchService.createAPIObservable(name));
this.searchService.createAPIObservable(name)
.subscribe(results => this.results = results);
})
} }
} }

Loading…
Cancel
Save