使用打字稿,Angular 6+和rxjs,如何最好地向调用者表示HTTP响应内容为空(Content-Length = 0)?
如果未在方法调用中指定类型(get
,post
等),则返回Observable<Object>
,这对响应内容具有误导性,因为可能会尝试使用给定的对象
let response: Observable<Object> = httpClient.post('...');
response.subscribe(o => ...);
在这种情况下,o
始终为null,但这不是显式的,也不由编译器检查。
一个更好的解决方案是返回Observable<null>
,但是我发现语义是模棱两可的,因为null也可以引用null数据(例如,没有电话号码的客户会将phoneNumber属性设置为null)
答案 0 :(得分:2)
您可以创建一种以Observable
的形式发送请求的方法,
// Add a new comment
addComment (body: Object): Observable<Comment[]> {
let bodyString = JSON.stringify(body); // Stringify payload
let headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
let options = new RequestOptions({ headers: headers }); // Create a request option
return this.http.post(this.commentsUrl, body, options) // ...using post request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any
}
// Update a comment
updateComment (body: Object): Observable<Comment[]> {
let bodyString = JSON.stringify(body); // Stringify payload
let headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
let options = new RequestOptions({ headers: headers }); // Create a request option
return this.http.put(`${this.commentsUrl}/${body['id']}`, body, options) // ...using put request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any
}
// Delete a comment
removeComment (id:string): Observable<Comment[]> {
return this.http.delete(`${this.commentsUrl}/${id}`) // ...using put request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any
}
或者像下面这样简单地使用HttpClient
:
getConfigResponse(): Observable<HttpResponse<Config>> {
return this.http.get<Config>(
this.configUrl, { observe: 'response' });
}
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions)
.pipe(
catchError(this.handleError('addHero', hero))
);
}
答案 1 :(得分:1)
您可以使用Observable.empty()
或
empty()
(如果您是从rxjs
导入的)
答案 2 :(得分:1)
您要查找的内容确实存在,并且其正确类型为Observable<void>
。就像您说的那样,null
是可由任何Observable生成的常规值。在RxJS 6中,它由empty()
表示,它与其他任何Observable一样,但是不发出任何next
值,而只是发送complete
信号。
import { empty, EMPTY } from 'rxjs';
empty().subscribe(...) // will receive just the `complete` notification
// or you can use EMPTY
EMPTY.subscribe(...)
通过这种方式,您还可以使用Observable<void>
运算符将任何Observable转换为ignoreElements()
。
还有never()
和NEVER
可观察对象,但不要将它们误认为empty()
,因为它们不会发出任何东西(甚至不发出complete
通知)。