本文章將會是閱讀官方文件 Get data from a server 內容所做的筆記。
本章節會教如何透過 Angular 的 HTTP 功能,來取得、新增、編輯、刪除有關英雄的資料。
Angular 是透過 HTTPClient 這個功能來達到發出 HTTP 請求來跟遠端伺服器互動。
Step1.
我們要在 AppModule 中引用 HttpClientModule 模組。並在 AppModule 的 imports 加入這個模組。
--- app.module.ts ---
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
//...,
HttpClientModule
]
})
在官方文件中,提供了一個 In-memory Web API package 的模組,讓我們可以使用 Angular 的 HTTPClient 模組來跟 In-memory Web API package 取資料,來模仿與遠端伺服器取資料的情境。
這部分就跟這官方文件教的安裝 In-memory Web API package 的步驟,在你的專案中安裝這個套件,並在安裝完成之後,記得在 app.module.ts 中引入這個套件。
輸入指令 ng generate service InMemoryData
,會發現在專案資料夾中出現 in-memory-data.service.ts 這個檔案,我們接下來就要在這個檔案中加入英雄資料的資料庫內容。
這邊的內容就是按照官方文件所給的內容加入到 in-memory-data.service.ts 檔案中就可以了,這邊就先不贅述了。
接下來,我們就在 HeroService 加入 HTTPClient 的功能,就可以在元件裡面透過它來發送 HTTP 請求囉。
Note:
有注意到嗎! 在 HeroService 所屬的模組 AppModule 我們先引入了 HttpClientModule ,接著,才在使用 http 請求的 HeroService 引入 HTTPClient ,才有辦法使用 HTTP 請求。
--- hero.service.ts ---
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({ providedIn: 'root' })
export class HeroService {
private heroesUrl = 'api/heroes';
constructor (
private http: HttpClient,
) {}
/* 原本取得英雄資料的方法
getHeroes(): Observable<HERO[]> {
const heroes = of(HEROES);
this.messageService.add('HeroService: fetched heroes');
return heroes;
}
*/
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
}
}
除了引入了 HttpClient 和 HttpHeaders。
也定義了目標資料庫的路徑 heroesUrl = 'api/heroes'
。
接著,將原本的 getHeroes 函式,改為用 http 的 get 方法從目標 url 中取回英雄資料。
所有的 HttpClient 的方法都會回傳屬於某個 Observable 實例的內容。
一般來說 RxJS 中的 Observable 是具有可以回傳好幾個數值的特性,但是,來自 HttpClient 的 Observable 就只會傳出一個值,並在傳出這個值之後,就不會再傳出任何值了。
引入 catchError 和 pipe 模組,利用 pipe 將 catchError 模組的內容,接在某些取 API 回傳資料的程式後面,用以做錯誤處理的對應。
--- hero.service.ts ---
import { catchError, map, tap } from 'rxjs/operators';
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
catchError(this.handleError<Hero[]>('getHeroes', []))
);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
定義目標路徑為 api/heroes/id。前面的 baseUrl 我們再前面有定義過了,並將它設為變數 heroesUrl 的內容。後面的 id 就是要被獲取詳細資料的英雄的 id。
--- hero.service.ts ---
getHero(id: number): Observable<Hero> {
const url = `${this.heroesUrl}/${id}`;
return this.http.get<Hero>(url).pipe(
catchError(this.handleError<Hero>(`getHero id=${id}`))
);
}
這邊要注意,這邊的函式名稱是 getHero 其中 Hero 是單數,而上面的是 getHeroes 其中的 Heroes 是複數,兩者不相同喔,要注意一下~
這邊做一個小總結,到這邊我們知道了
this.HttpClient.get
這種語法來執行 GET 的請求。