Ionic with Angular 5 and new HttpClient


#1

Hi,
I discovered a big problem.
With the new HttpClient, you can get full response only if you use in the options {observe: ‘response’}. That’s ok and works good. But if you want to build your application, I get a typescript error, because typescript doesn’t know that it gets a full response and can’t find the property status on the response.

A StackBlitz example of the bug:

I’ve written a HttpService my own, which handles many things and one function named getOptions which return the options object dynamically and therefore typescript doesn’t know what comes back from the http method. So I can’t build my app anymore and I’m not up to insert everywhere statically. (which didn’t work either for me). For different status codes, I have different things to do.
I hope, someone can help me or one man of the Ionic team sees it.
And yes, I know it’s basically an angular problem.
Best wishes, Philipp


#3

You can use TS generics to ensure TS expects a particular type of response.


#4

You do it static. Please don’t reply, if you haven’t understand the issue.


#5

Ok. I’ll look over it.


#6

I’ve made a StackBlitz in the http.service.ts, you can see that typescript underlines the res.status, because it doesn’t know that it gets the full response


#7

Like this: https://angular.io/guide/http#typechecking-the-response


#8

Thanks for your update:
I’ve updated the StackBlitz with an interface of my type, but it doesn’t work eithere.
If you go in the edit mode, you can see it in http.service.ts:


#9

That’s compiling wrong. Look at the type of res. That shouldn’t be happening. What version of Typescript are you using? It should be 2.4.2, unless Ionic changed it recently.


#10

Ok, I use Typescript version 2.6.2 on my local pc. On StackBlitz I can’t see typescript version in the dependencies. So you say it’s a problem with the typescript version and I should change to version 2.4.2?


#11

All I know for sure is that your StackBlitz is parsing it wrong. I just put a similar line into my system, and my system parses the same way the Angular docs say it is supposed to parse. The only option for the type is the one specified in the generic.


#12

Looks as though Angular does not support TS 2.6 yet.


#13

I’ve tried it with Typescript 2.4.2 but still gettings this error:

Property ‘status’ does not exist on type ‘HttpEvent<HttpResponse>’. Property ‘status’ does not exist on type ‘HttpProgressEvent’.

I try to do it like this:

this.http.get<HttpResponse<any>>(this.appConfig.apiEndpoint+path, options).subscribe((res) => {

#14

this.http.get<putTypeHere>('').subscribe(test => true);

The type of test is whatever type you put in putTypeHere. If that isn’t happening for you, something is wrong.


#15

I have tried it with with <HttpResponse> and also with my own interface , but it doesn’t seem to work. I get the error I posted before.


#16

Which IDE are you using?


#17

I’m using Webstorm as IDE.


#18

Copypaste the line of code I provided. If that works, then your options are suspect. If it doesn’t work, then your system configuration is the problem. I don’t have any better advice than that. I’m seeing no issues on my end, so I don’t think this is a bug.


#19

Ok, but please try to paste this code and compile it afterwards:

getRequest(path, callback) {
    this.getOptions((options) => {
      this.http.get<HttpResponse<any>>(this.appConfig.apiEndpoint+path, options).subscribe((res) => {
        console.log("res off "+path+": ", res);
        if(res.status == 200) {
          console.log(res.body);
          callback({status: res.status, body: res.body});
        } else {
          callback({error: res});
        }
      }, error => {
          console.log("error of "+path+": ", error);
          callback({error: error});
      });
    });
  }
  getOptions(callback) {
    callback({
      observe: 'response'
    });
  }

#20

If that could help I noticed that following code would be accepted by typescript

getRequest(path, callback) {
   this.http.get(this.appConfig.apiEndpoint+path, {
     observe: 'body'
   }).subscribe((res: StandardResponse)           => {
      console.log("res of "+path+": ", res);
      //i pass observe: 'response', but it doesn't get it
      if(res.status == 200) {
        console.log(res.body);
        callback({status: res.status, body: res.body});
      } else {
        callback({error: res});
      }
    }, error => {
        console.log("error of "+path+": ", error);
        callback({error: error});
    });
}

respectivelly when options isn’t a callback.

also is maybe this post related? https://github.com/angular/angular/issues/18586


#21

Yeah, this works. But my problem is, that I can’t pass it dynamically