Sunday, September 17, 2017

the new HttpClient in Angular 4

  1. You import HttpClientModule, at both your module and your component, like so:
    import { HttpClientModule } from '@angular/common/http';
    and a private http: Http variable becomes private httpClient: HttpClient at your component. You no longer need Http and Response. Response may be sidestepped as it is now much easier to map off what you get back like so:
    this.httpClient.get("http://www.example.com").map((foo:Foo) => {
    ...and like so...
    this.httpClient.get<Foo>("http://www.example.com").map((foo) => {
    ...these are examples of: "Typed Requests"
  2. Remember how in ASP.NET MVC how you didn't necessarily have to communicate in JSON and you could instead set messaging to be in XML? Well, there is no XML support with the new HttpClient, but it does allow for a few variations from JSON. You may add a second options parameter to a get call like so:
    this.httpClient.get("http://www.example.com", {
       observe: body,
       responseType: 'text',
    }).map((foo) => {

    This is going to scrape the guts of whatever there is to see as text (even if it is JSON) and return it in kind. Other options for responseType are "blob" for a file, "json" which is the default and which you don't really need to explicitly state, and, finally, "arraybuffer" too. A combo of "response" for the observe setting and "text" for the responseType setting does something similar but the text that comes back seems to be interpreted as one big string in a JavaScript object instead of merely text alone. Beyond "observe" and "responseType" other parameters for this options object include "headers" for passing headers and "body" for passing an outbound package as is the case in .put implementations. In using a .put instead of .get, the options will typically be the third parameter (the two beforehand being first the URL and the second the object you are putting out there) and not the second as in the case of a .get, but if you use "body" with a .put you may skip the second property.
  3. Setting "observe" to "event" allows for some interesting things downstream in a .subscribe, for example:
    .subscribe(
       (response: HttpEvent<Object> => {
          if (response.type === HttpEvent.Sent) {

    If this is downstream of a .put, which, yes, has to have a response come back in the Angular way of doing things as if someone is putting pins in Roy Fielding's voodoo doll (PUT should be fire and forget) well then the if statement is gonna get hit twice. First the event out to the endpoint will successfully meet the criteria in the .Sent and then the response back will not. This allows you to pry into events. Beyond "Sent" there is "Response" and "User" and "ResponseHeader" and "DownloadProgress" and "UploadProgress" too. If you log response.type to the console, Sent has a type of 0, UploadProgress a type of 1, and DownloadProgress a type of 3 so there is a numeric encoding behind these guys. Loop in HttpEvent like so:
    import { HttpEvent } from '@angular/common/http';
  4. headers: new HttpHeaders().set("foo", "bar").append("baz", "qux")
    ...is the way to do the headers and you can loop them in with...
    import { HttpHeaders } from '@angular/common/http';
    ...and also you may make a standalone HttpHeaders const variable that you assign in lieu of the immediate assignment.
  5. params: new HttpParams().set("key", "value")
    ...is how you similarily add, cleanly, the URL line parameters without actually jamming them in the URL line. Loop HttpParams in like so...
    import { HttpParams } from '@angular/common/http';
  6. const act = new HttpRequest('PUT', 'http://www.example.com', this.myThing, {});
    this.httpClient.request(act);

    ...is another shape of things and if you put...
    reportProgress: true
    ...in the options you will be able to listen for the upload and download events.
  7. import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest }
          from '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    export class WhateverInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          return next.handle(httpRequest);
       }
    }

    ...is an example of an interceptor. You would put this is its own file and whatever.interceptor.ts would be a pretty spiffy name. You will loop this into a module and all of the REST calls that use this new approach that the module governs will use the interceptor midstream in calls! Import the following at a module:
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    You loop this in a providers in the module by giving an object as an array item instead of a name per the norm. (If you have more than one interceptor in providers then they will be run in the order specified sequentially in providers.) The object is:
    {provide: HTTP_INTERCEPTORS, useClass: WhateverInterceptor, multi: true}
  8. import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
          '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    export class WhateverInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          const copy = httpRequest.clone({headers:
                httpRequest.headers.append('yin,'yang')});
          return next.handle(copy);
       }
    }

    ...is a way to add a header to all outbound requests and you may also add a param all the time like so...
    import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
          '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import { Injectable } from '@angular/core';
    import { TokenService } from from '../services/token.service';
    export class WhateverInterceptor implements HttpInterceptor {
       constructor(private tokenService: tokenService) {}
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          const copy = httpRequest.clone({headers:
                httpRequest.params.set('token,this.tokenService.giveToken())});
          return next.handle(copy);
       }
    }
  9. import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
          '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/do';
    export class WhateverInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
             Observable<HttpEvent<any>> {
          return next.handle(httpRequest).do(
             thing => {
                console.log(thing);
             }
          );
       }
    }
    ...has you writing stuff to the console for every event. Note that we are using a .do and not a .subscribe as .subscribe actually consumes the Observable in scope and would sabotage a later .subscribe.
  10. https://angular.io/guide/http has some documentation and, again, all of the notes here were stolen out of an online training I watched.

No comments:

Post a Comment