Updating to Angular 6’s new HttpClientModule

The purpose of this post is to show a worked example of updating an existing Angular 6 solution to use the new HttpClientModule available with version 6 of Angular. This new module provides a higher level abstraction for developers to deal with when making HTTP requests when compared to the Http module available in Angular <6.0.0.

Changes Required

Packages

There are no actual package changes strictly necessary in order to make use of the HttpClientModule – it is included as part of the @angular/common module. However to ensure all references to the legacy HttpModule have been completely eradicated it is best to remove the module from package.json so the solution will not compile successfully until they are all removed.

Code changes

The old Http service provided by HttpModule only dealt with simple HTTP requests & responses, leaving the parsing of request bodies and subsequent responses to consumers. Almost all the HTTP requests to my solution’s ASP.NET Core 2 backend are JSON based and require a common set of headers (XSRF token, Content-Type), so I had previosuly authored my own HttpService to hide some of the complexity around making such requests, leveraging the Angular Http service plus third party library TypedJSON, along with other custom abstractions around obtaining request headers (RequestHeadersService) and obtaining and managing XSRF tokens (XSRFTokenService). Much of this bespoke code's functionality is now either provided OOTB by the new HttpClient or alternatively can be wired in via various extensibility points.

Since my solution is fairly loosely coupled, there are only a small number of references to my bespoke HttpService I made the decision to simply remove it rather than update it to be just a thin wrapper around Angular's HttpClient – obviously on complex and/or larger projects it may be appropriate to retain the wrapper and delay tackling that technical debt to another day. The change to HttpClient markedly simplifies consumer code, for example:

The functionality formerly provided by XSRFTokenService to HttpService also needed to be replicated in the HttpClient world. One way to achieve this to create a HttpInteceptor implementation which can transform requests before they are sent:

Note how the code simply passes through requests for the token endpoint without modification – this is necessary otherwise a recursive loop gets entered until a stack overflow occurs, as the HttpInteceptor is registered to intercept all HTTP requests thusly (note the use of the ClassProvider provider interface):

Module Loading

With my code now building successfully using the Typescript compiler, it became time to try testing it in the browser. As those of you who read the previous installment of this series will know, this solution use the SystemJS ES Module Loader as it has its origins in the Angular 2 RC Quickstart repo. And because of this things don't work automagically like they would if using ng serve. And so it again proved with these changes.

After many failed attempts to get HttpClientModule to load correctly in the browser with the SystemJS ES Module Loader I resorted to the sledgehammer apporach of simply adding an explicit mapping from its module name to its corresponding UMD JS bundle location under the node_modules directory tree, also taking the opportunity to remove other unneeded cruft:

It seems that the HttpClientModule UMD JS bundle does not follower earlier naming conventions and consequently the ngPackage convention based loading is broken, at least for this module. If someone has a more eloquent way to get this to work please shoot me a message via LinkedIn.

Other articles in this series

  1. Upgrading Angular 4 to Angular 6 without tooling support
  2. Upgrading from HttpModule to HttpClientModule
  3. Upgrading Angular 6 to Angular 8 without tooling support
  4. Upgrading from RxJS code from chainable operators to pipeable operators (TBD)
  5. Merging these changes in to my ASP.NET Core 2 SignalR development branch… gulp! (TBD)