订阅或不订阅将数据发布到API

时间:2019-02-21 18:11:41

标签: angular angular6 angular7 angular-httpclient

在Angular 7中,我正在从API获取和发布数据。

获取

  • 要获取数据,我使用的是Observable(posts $)和管道/地图;
  • 我正在组件HTML中使用异步,并且未使用订阅
  • 这是我最近在Angular文档中看到的方法。

POST

  • Service Post方法还返回数据:
    可能的验证错误或创建的帖子的ID。
    当API返回它们时,我需要获取它们中的任何一个。

但是,在调用该服务以进行POST时,以下操作无效:

this.postService.addPost(model).pipe();

除非我按如下方式使用subscribe

this.postService.addPost(model).pipe().subscribe();

问题 我如何在不使用订阅的情况下发布到API?这有道理吗?

组件

export class PostComponent implements OnInit {

  posts$: Observable<GetPostsModel[]>;

  constructor(private postService: PostService) { }

  ngOnInit() {
    this.posts$ = this.getPosts();
  }

  addPost(model: AddPostModel) {

    this.postService.addPost(model).pipe().subscribe();

  }

  getPosts(): Observable<GetPostsModel[]> {

    return this.postService.getPosts().pipe(

      map((response: GetPostsResponse) => 

        return {
          // Map Response to GetPostsModel here 
        };

      }));

  }

}

服务

export class PostService {

  constructor(private httpClient: HttpClient) { }

  public addPost(model: AddPostModel): Observable<AddPostResponse>> {

    const headers = new HttpHeaders({ 'Content-Type': 'application/json' });

    return this.httpClient.post<AddPostResponse>>('posts', model, { headers: headers });

  }

  public getPosts(): Observable<GetPostsResponse>> {
    return this.httpClient.get<GetPostsResponse>>('posts');
  }

}

2 个答案:

答案 0 :(得分:1)

  

在不使用订阅的情况下如何发布到API?

不能,必须始终订阅。如果您不关心结果,则不必提供回调。这是完全有效的:

this.postService.addPost(model).subscribe();

旁注:在这种情况下,您不需要空的pipe

另请参阅Angular 2 http.post() is not sending the requestHttpClient - Always subscribe!文档。

  

始终订阅!

     

在您对该方法返回的可观察对象上调用subscription()之前,HttpClient方法不会开始其HTTP请求。对于所有HttpClient方法来说都是如此。

答案 1 :(得分:0)

任何Http操作(get / post / put / etc)返回的Observable 需要订阅。

但是在某些情况下,Angular 自动会为您处理该订阅。

例如:

  • 使用异步管道将自动订阅返回的observable。

  • 使用路由解析器将自动订阅返回的可观察对象。

在其他所有情况下(例如您的Post示例),您都需要订阅。

更新

仅在需要通过一组运算符传递响应时,才需要添加pipe。通常,您至少需要catchError运算符。我经常在开发过程中添加tap只是出于调试目的,但这不是必需的。

以下是我的一项Post操作示例:

  createProduct(product: Product): Observable<Product> {
    const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    return this.http.post<Product>(this.productsUrl, product, { headers: headers })
      .pipe(
        tap(data => console.log('createProduct: ' + JSON.stringify(data))),
        catchError(this.handleError)
      );
  }

我很少在客户端代码中看到pipe的使用。对于“关注点分离”,通常,数据映射/操作是在服务中完成的……除非您需要做一些组件唯一的事情。

但是就这样:

this.postService.addPost(model).pipe().subscribe();

不通过某些操作员传递响应而进行管道操作无济于事。