diff --git a/day3/README.md b/day3/README.md index 586c589..eb2b645 100644 --- a/day3/README.md +++ b/day3/README.md @@ -8,6 +8,7 @@ 1. Make typing into an input field an observable 1. Have a subscriber act only after a pause in events from an observable 1. Check for distinct events from an observable +1. Create a service for an observable ## Describe publish/subscribe model and how it relates to Observables @@ -173,3 +174,105 @@ ngOnInit() { }) } ``` + +## Create a service for an observable + +Our code could be cleaner. Let's move the HTTP action to a service, so that other components can use it if they want. First create `src/app/search/search.service.ts`. Now have it export a class like normal: + +```javascript +export class SearchService { +} +``` + +Since this is a service, not a component, let's make it `Injectable`: + +```javascript +import { Injectable } from '@angular/core'; + +@Injectable() +export class SearchService { +} +``` + +Now we can inject the service in components. + +Next, let's create a method that will make the API call and return the observable. Copy the `this.http.get('http://swapi.co/api/people/?search=' + name)` code from `src/app/search/search.component.ts` to `src/app/search/search.service.ts`: + +```javascript +export class SearchService { + createAPIObservable(name){ + return this.http.get('http://swapi.co/api/people/?search=' + name); + } +} +``` + +We need to import the Http module into `src/app/search/search.service.ts`, though: + +```javascript +import { Http } from '@angular/http'; +``` + +And inject it into the component: + +```javascript +export class SearchService { + + constructor(private http: Http) {} + + createAPIObservable(name){ + return this.http.get('http://swapi.co/api/people/?search=' + name); + } + +} +``` + +Now in `src/app/search/search.component.ts` import the new service: + +```javascript +import { SearchService } from './search.service' +``` + +Inject the service into the component in `src/app/search/search.component.ts`: + +```javascript +constructor( + private http: Http, + private searchService: SearchService +) { } +``` + +And replace `this.http.get()` with the service: + +```javascript +this.searchSubject + .debounceTime(300) + .distinctUntilChanged() + .subscribe(name => { + this.searchService.createAPIObservable(name) + .subscribe(response => this.results = response.json().results); + }) +``` + +You might see an error in your Chrome console. We still need to specify our new service as a provider, either at the app level or at the component level. Let's do at the app level, so that other components can use it if they need to later. Edit `src/app/app.module.ts` to add the import: + +```javascript +import { SearchService } from './search/search.service' +``` + +Now add it as a provider in `src/app/app.module.ts`: + +```javascript +@NgModule({ + declarations: [ + AppComponent, + SearchComponent + ], + imports: [ + BrowserModule, + HttpModule, + FormsModule + ], + providers: [SearchService], //edit this line + bootstrap: [AppComponent] +}) +``` diff --git a/day3/starwars/src/app/app.module.ts b/day3/starwars/src/app/app.module.ts index c57e8df..525b0f4 100644 --- a/day3/starwars/src/app/app.module.ts +++ b/day3/starwars/src/app/app.module.ts @@ -7,6 +7,8 @@ import { SearchComponent } from './search/search.component'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; +import { SearchService } from './search/search.service' + @NgModule({ declarations: [ AppComponent, @@ -17,7 +19,7 @@ import { HttpModule } from '@angular/http'; HttpModule, FormsModule ], - providers: [], + providers: [SearchService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/day3/starwars/src/app/search/search.component.ts b/day3/starwars/src/app/search/search.component.ts index 332feff..0501cbe 100644 --- a/day3/starwars/src/app/search/search.component.ts +++ b/day3/starwars/src/app/search/search.component.ts @@ -5,6 +5,8 @@ import { Subject } from 'rxjs/Subject' import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged'; +import { SearchService } from './search.service' + @Component({ selector: 'app-search', templateUrl: './search.component.html', @@ -16,7 +18,8 @@ export class SearchComponent implements OnInit { searchSubject = new Subject(); constructor( - private http: Http + private http: Http, + private searchService: SearchService ) { } findCharacter(name){ @@ -28,7 +31,7 @@ export class SearchComponent implements OnInit { .debounceTime(300) .distinctUntilChanged() .subscribe(name => { - this.http.get('http://swapi.co/api/people/?search=' + name) + this.searchService.createAPIObservable(name) .subscribe(response => this.results = response.json().results); }) } diff --git a/day3/starwars/src/app/search/search.service.ts b/day3/starwars/src/app/search/search.service.ts new file mode 100644 index 0000000..53aaed6 --- /dev/null +++ b/day3/starwars/src/app/search/search.service.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; + +@Injectable() +export class SearchService { + + constructor(private http: Http) {} + + createAPIObservable(name){ + return this.http.get('http://swapi.co/api/people/?search=' + name); + } +}