Notes on Angular "HTTP Client" Guide
A working understanding of reactive programming with RxJS Observables for Angular was listed as a prerequisite to Angular guide for HTTP client. After my long and convoluted tangent to learn RxJS, I felt I was finally ready to dive in and learn how to apply RxJS to handle HTTP transactions in an Angular web application.
One of the most powerful aspects of RxJS is the declaration of an Observable pipeline is a template. It means we can set one up independently of using them. To use them we call subscribe()
, and it is a template that we can reuse by calling subscribe()
again. An unexpected downside of this power is that nothing actually happens until we call subscribe()
, which can be counterintuitive when we use the Angular HTTP client for operations like DELETE. Outside of Angular/RxJS, such things are fire-and-forget but here we have to subscribe()
to start things in motion even if we don't really care about the results of that subscription. This is apparently a common mistake because it is called out multiple times on this page. I also remember seeing this in the "Tour of Heroes" tutorial, which was absolutely wild when I first saw it. I now understand why it behaves that way, but I still think it is weird.
Unrelated to RxJS, I thought "Requesting a typed response" section was interesting. It enables TypeScript compile-time checking, which helps keep our code straight, but we have to remember we're still on the hook for runtime checking. Sanitizing data is important for security! This also explains why the example code would copy elements from the result and not blindly copy the whole object. Blind copy would leave our code vulnerable to a maliciously written object that comes with its own toString()
or something that is likely to get called in the context (and authority!) of our application code.
With my current basic understanding of RxJS and HTTP, the first half of this page was fairly straightforward. Then things got weird with "interceptors". I understand it is a very powerful concept that allows separation of concerns across different chunks of code, each handling an aspect of HTTP activity. But getting them to all play nicely together seems to be a challenging task with lots of room for error. A very powerful gun aimed at our feet, it seems.
Even just loading them up has pitfalls. There's a recommendation to load them with a "barrel" but I haven't understood the tradeoffs to use/not use them. I also understood that load order mattered, but it didn't cover symptoms of getting the order wrong. There's even a back channel for application code to control interceptors (passing metadata) via HttpContextToken object.
An application of interceptor that looked very impressive was the ability to return a cached value immediately while also issuing the HTTP request. Then the real updated live value from the server is given, all on the same Observable! This is something that would have been really complicated to do with plain JavaScript Promise (async/await) and the first real "A-ha" for me to see power of RxJS in action.
Interceptors are also how Angular performs client-side work to protect against cross-site request forgery (XSRF) adding an XSRF-TOKEN in the header. It's only part of the solution, though. It needs to mesh with server-side code to set the token and verify the token. It is on my "To-Do" list to find an implementation example, probably with Express.
And finally, there's a section on using HTTP client in unit tests. This is the section I can put to work immediately.