Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A close look to Angular's new HttpClient

A close look to Angular's new HttpClient

Presentation from ng-be in December 2017.

Manfred Steyer

December 09, 2017
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. A close look to
    Angular's new HttpClient
    Manfred Steyer
    SOFTWAREarchitekt.at

    View full-size slide

  2. About me …
    • Manfred Steyer
    • Angular Workshops and Consultancy
    • SOFTWAREarchitekt.at
    • Google Developer Expert (GDE)
    Page ▪ 2
    Manfred Steyer

    View full-size slide

  3. In the old
    days,
    everything
    was better ;-)

    View full-size slide

  4. Just a few examples …

    View full-size slide

  5. Http in Angular
    Http (Service)
    • Angular 2+
    • Most Common Use
    Cases
    (80:20 principle)
    • Experimental
    • Deprecated with 5.0
    HttpClient
    • Angular 4.3
    • A lot of additional
    features
    • Full comfort we know
    from $http

    View full-size slide

  6. Contents
    • Short overview of Basics
    • Custom Data Formats (Binary, Text)
    • Progress Information
    • Interceptors for Extensions
    • Token-based Security

    View full-size slide

  7. angular-crud

    View full-size slide

  8. HttpClient
    HttpClientModule and HttpClient from @angular/common/http
    let url = 'http://www.angular.at/api/hotel';
    let headers = new HttpHeaders()
    .set('Accept', 'application/json');
    let params = new HttpParams()
    .set('city', this.city);
    this
    .http
    .get(url, { headers, params })
    .subscribe(
    hotels => console.debug('hotels', hotels),
    err => console.error('err', err)
    );

    View full-size slide

  9. Getting the full HttpResponse
    save(entity: HotelBooking): Observable {
    let url = […]
    let headers = […]
    return this.http
    .post(url, entity, {headers, observe: 'response'})
    […]
    }

    View full-size slide

  10. Getting the full HttpResponse
    save(entity: HotelBooking): Observable {
    let url = […]
    let headers = […]
    return this.http
    .post(url, entity, {headers, observe: 'response'})
    .pipe(
    map((response: HttpResponse) => {
    console.debug('status', response.status);
    console.debug('body', response.body);
    return response.headers.get('Location');
    }));
    }

    View full-size slide

  11. Main Idea: Mock the HttpBackend
    HttpClientTestingModule
    Your Code
    Test
    HttpClient
    HttpBackend Server
    MockBackend

    View full-size slide

  12. Testing
    it('can load hotels by city', () => {
    let service: HotelService = TestBed.get(HotelService);
    let ctrl: HttpTestingController = TestBed.get(HttpTestingController);
    […]
    });

    View full-size slide

  13. Testing
    it('can load hotels by city', () => {
    let service: HotelService = TestBed.get(HotelService);
    let ctrl: HttpTestingController = TestBed.get(HttpTestingController);
    service.find({ city: 'Graz' }).subscribe(
    hotels => expect(hotels.length).toBe(2),
    err => fail(err)
    );
    […]
    });

    View full-size slide

  14. Testing
    it('can load hotels by city', () => {
    let service: HotelService = TestBed.get(HotelService);
    let ctrl: HttpTestingController = TestBed.get(HttpTestingController);
    service.find({ city: 'Graz' }).subscribe(
    hotels => expect(hotels.length).toBe(2),
    err => fail(err)
    );
    let req = ctrl.expectOne('/hotel?city=Graz');
    expect(req.request.method).toBe('GET');
    […]
    });

    View full-size slide

  15. Testing
    it('can load hotels by city', () => {
    let service: HotelService = TestBed.get(HotelService);
    let ctrl: HttpTestingController = TestBed.get(HttpTestingController);
    service.find({ city: 'Graz' }).subscribe(
    hotels => expect(hotels.length).toBe(2),
    err => fail(err)
    );
    let req = ctrl.expectOne('/hotel?city=Graz');
    expect(req.request.method).toBe('GET');
    req.flush([{id: 1, name: 'Hotel Mama'}, {id: 2, name: 'Budget Hotel'}]);
    ctrl.verify();
    });

    View full-size slide

  16. Custom Data
    Formats (Text
    and Binary)

    View full-size slide

  17. Using XML
    findById(id: string): Observable {
    […]
    return this.http
    .get(url, { headers, params, responseType: 'text'})
    […]
    }

    View full-size slide

  18. Using XML
    findById(id: string): Observable {
    […]
    return this.http
    .get(url, { headers, params, responseType: 'text'})
    .pipe(
    switchMap(xmlString => {
    let observableFactory = bindCallback(parseString);
    return observableFactory(xmlString, parserOptions);
    }),
    map(js => js[1].hotelBooking)
    );
    }
    import { parseString } from 'xml2js';

    View full-size slide

  19. Interceptors

    View full-size slide

  20. Idea
    • Providing a hook
    • Modify requests and responses globally
    • Including Headers, e. g. for Auth.
    • Parsing Data Formats, like XML
    • Error Handling
    • Caching
    • …

    View full-size slide

  21. Chain of Responsibility
    Logic
    (HttpRequest)
    Interceptor
    Interceptor
    Request
    Response

    View full-size slide

  22. DEMO
    Sending Access Token for Auth
    Global Error Handler for Auth

    View full-size slide

  23. Conclusion
    observe:
    response,
    events, …
    responseType:
    text, blob, …
    Interceptor
    Chain
    The Dark
    Knight: Best
    Movie ever!

    View full-size slide

  24. Contact und Downloads
    [mail] [email protected]
    [blog] SOFTWAREarchitekt.at
    [twitter] ManfredSteyer

    View full-size slide