简体   繁体   English

Ionic-Angular 2-订阅http.post响应

[英]Ionic - Angular 2 - subscribe to http.post response

I have a bit of code to share with you. 我有一些代码可以与您分享。 It's from an Ionic 2 project. 它来自Ionic 2项目。 I think it's bad practice what I did, so I want to refactor it right. 我认为这是不好的做法,所以我想正确地重构它。

I'm sending an image in base64 to an API, the API saves the image as .png on the server, then sends me back a response with this image's URL on the API server. 我正在将base64中的图像发送到API,API在服务器上将图像另存为.png,然后在API服务器上向我发送带有该图像URL的响应。 The app shows a loading screen while waiting for the API response, so you can't make multiple calls in the same time. 该应用程序在等待API响应时会显示一个加载屏幕,因此您无法同时进行多个调用。 Also the API replies with 1 response for each call, and that's it. API还会为每个调用回复1个响应,仅此而已。

Here's the simple call: 这是简单的调用:

api.service.ts api.service.ts

private _imgUrl = new Subject<string>();

public getImgUrl(imgURI: any): Observable<string> {
  this.apiImgUrl(imgURI);
  return this._imgUrl.asObservable();
}

private setImgUrl(url: any) {
  this._imgUrl.next(url);
}

private apiImgUrl(imgURI: string) {
  var data  = {
    src: imgURI
  };
  var postData = JSON.stringify(data);

  var headers = new Headers({ 'Content-Type': 'application/json' });
  var options = new RequestOptions({ headers: headers });

  this.http.post(
      'my-api-url.com', 
      postData, 
      options
    )
    .retry(3)
    .toPromise()
      .then((res) => {
        var body = res.json();
        this.setImgUrl(body);
      })
      .catch(this.handleErrorPromise);
}  

my-module.ts 我-module.ts

import { ApiService }   from '../shared';

...

private socialImageSubscription: Subscription;
private i = 0;

constructor(private _api: ApiService) {}

private getImageFromAPI(canvasURI) {
  this.socialImageSubscription = this._api.getImgUrl(canvasURI).subscribe((res:any) => {
     this.i++;
     console.log(this.i, 'socialImageSubscription', res.data);
    // doing something with the response
  });
}

Now, getImageFromAPI() is triggered by (click) . 现在, getImageFromAPI()(click)触发。 So if I click once, I get this console log: 因此,如果单击一次,将得到以下控制台日志:

1,"socialImageSubscription", www.apidomain.com/url1

On second click: 第二次单击:

2,"socialImageSubscription", www.apidomain.com/url2
3,"socialImageSubscription", www.apidomain.com/url2

On third click: 第三次单击:

 4,"socialImageSubscription", www.apidomain.com/url3
 5,"socialImageSubscription", www.apidomain.com/url3
 6,"socialImageSubscription", www.apidomain.com/url4

So each time I access getImageFromAPI() it creates a new subscription, while the previous subscriptions remains active. 因此,每次我访问getImageFromAPI()它都会创建一个新订阅,而先前的订阅仍处于活动状态。

How can I write this code properly? 如何正确编写此代码?

Try this : It should resolve your issue. 试试这个:它可以解决您的问题。

private getImageFromAPI(canvasURI) {
this._api.getImgUrl(canvasURI).subscribe((res:any) => {
         this.i++;
         console.log(this.i, 'socialImageSubscription', res.data);
        // doing something with the response
      }).unsubscribe();           // unsubscribe here
}

Unsubscribe it immediately, so that you don't have the subscriptions active. 立即取消订阅,这样您就不会激活订阅。 And also you don't need the subscription variable here. 另外,您在这里不需要订阅变量。

Played around a bit, and found what I was looking for: 玩了一下,发现我在找什么:

api.service.ts api.service.ts

private apiImgUrl(imgURI: string) {
  var data  = {
    src: imgURI
  };
  var postData = JSON.stringify(data);

  var headers = new Headers({ 'Content-Type': 'application/json' });
  var options = new RequestOptions({ headers: headers });

  return this.http.post(
      'my-api-url.com', 
      postData, 
      options
    )
    .retry(3)
    .toPromise()
      .then((res) => {
        var body = res.json();
        return body;
      })
      .catch(this.handleErrorPromise);
}  

my-module.ts 我-module.ts

import { ApiService }   from '../shared';

...

private i = 0;

constructor(private _api: ApiService) {}

private getImageFromAPI(canvasURI) {
  this._api.apiImgUrl(canvasURI).then((res:any) => {
     this.i++;
     console.log(this.i, 'socialImageSubscription', res.data);
    // doing something with the response
  });
}

The code is much easier to read, and removes the useless subscription. 该代码更容易阅读,并删除了无用的订阅。 The console logs are what you'd expect. 控制台日志就是您所期望的。 First click: 第一次点击:

1,"socialImageSubscription", www.apidomain.com/url1

On second click: 第二次单击:

2,"socialImageSubscription", www.apidomain.com/url2

On third click: 第三次单击:

 3,"socialImageSubscription", www.apidomain.com/url3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM