Using Angular HttpClient the right way

Written by kashyap.mukkamala | Published 2018/07/14
Tech Story Tags: http-client | angular-cli | javascript | angular

TLDRvia the TL;DR App

The HttpClient was introduced in Angular 4.3.x and provides significant improvement over the previous HTTP implementation. This article does not explain how to use the HttpClient which is sufficiently explained here.

In this article, we will instead be focusing on how to use the HttpClient, leverage its type safety and extend it for our customizations. There are ways to bypass the type safety which inadvertently happens when we are not careful. We will implement an approach which leverages classes and interfaces to provide a custom, type safe and consistent access to different entities.

Project Setup

Let us first set up a simple project using the angular-cli. You can install it using the following command if you have not already.

ng i -g @angular\cli

Now we will use the cli to create a new app.

ng new httpclient

Service Setup

Now we can set up the HttpClient to make the API calls, we will be retrieving the users from the endpoint https://jsonplaceholder.typicode.com/users. It is pretty straight forward to make the API call, so let us set up the appropriate service to do so.

Creating services with the help of angular cli is one of the best ways to do so. You can create one manually but its always easier to generate it using the CLI as it uses the latest syntax and creates the service, its spec and adds it to the nearest module as a provider.

ng generate service services/user

Once the service is set up, we just need to inject the HttpClient and we are ready to make the API call.

Making the API call

To make the API call, we can simply inject the HttpClientModule module in the main application module as follows:

<a href="https://medium.com/media/a9deac64ca207a48a7baed840aaae002/href">https://medium.com/media/a9deac64ca207a48a7baed840aaae002/href</a>

Next we add the method necessary to make the API call for getting the users from the URL https://jsonplaceholder.typicode.com/users as shown below:

<a href="https://medium.com/media/943d41274451ab7c206f5486b048b83e/href">https://medium.com/media/943d41274451ab7c206f5486b048b83e/href</a>

Last and final piece of code necessary to get the users list is to make the call to service method. You can add this logic to either the constructor or the OnInit method based on your preference. We will go with the constructor for now to keep the example simple.

<a href="https://medium.com/media/baab191ef11904f0191e89064dee06a6/href">https://medium.com/media/baab191ef11904f0191e89064dee06a6/href</a>

To start the application, we can run the following command and open http://localhost:4200.

ng start

Once the application is open on the browser, open the console and you can see the list fo users logged as below:

As expected, this works and logs the list of users that were retrieved, but there is no type safety being enforced. One of the great advantages with typescript projects is that we can leverage interface.

User Interface

Now that we have the API call working as expected, let us create the user interface which we will use in the service later on. We will once again be using the angular cli to create the interface:

ng generate interface interfaces/user

We can now add the fields necessary to the interface that we just created.

<a href="https://medium.com/media/4ff39c472af9a05ff3c8eac2e9241f08/href">https://medium.com/media/4ff39c472af9a05ff3c8eac2e9241f08/href</a>

Updated Component

Based on the API response we were expecting, we have created the interface for the User object. We will now be embedding the User interface in all our service calls which is an easy change.

In the service:

<a href="https://medium.com/media/8d31007b43eeb4e9d8a2199507093685/href">https://medium.com/media/8d31007b43eeb4e9d8a2199507093685/href</a>

and in the component:

<a href="https://medium.com/media/046c26a38de0d520b15724f062622ea7/href">https://medium.com/media/046c26a38de0d520b15724f062622ea7/href</a>

It still works as expected:

Now one might wonder, what is the big deal with the interface, its not adding anything extra, not enforcing any rules, not adding default or new values etc. In short, Interface does not do much except enforce the structure of the User that we are are consuming in the app component.

Now consider the case where we want to filter out some fields from the response of the API or if we want to add some custom validations or modifications to the User. This is where we upgrade our User interface to a class and add all the properties or customizations that we need.

First, let us rename the User interface to BaseUser. We do this so that our new User class inherits from the BaseUser thus keeping the type check in place.

<a href="https://medium.com/media/fac705f642fcef62ec1815a9d3c8a7ad/href">https://medium.com/media/fac705f642fcef62ec1815a9d3c8a7ad/href</a>

Updated User class which implements the BaseUser

<a href="https://medium.com/media/4871bb47535e0ec5e377075bfb3826a0/href">https://medium.com/media/4871bb47535e0ec5e377075bfb3826a0/href</a>

For now, we are returning only the id and name so that we can test the changes and get an idea of how it works. Next, we need a way to invoke the this new class that we have created. This can be done in two ways:

  1. Add an Http Interceptor to change the user inflight, but might apply your change to all the calls.
  2. Invoke the User class on each of the record and update the structure of the object.

In this example, we want this change to apply only on our app component so we will go with approach #2.

<a href="https://medium.com/media/9d419739ee5b77cabb95aaae7ecd615d/href">https://medium.com/media/9d419739ee5b77cabb95aaae7ecd615d/href</a>

As you can see, we chained a simple pipe to our get call to capture the Observable and use the map operator from rxjs to iterate over the response and modify each record as new User class instance.

Result

And that is it. With these changes in, we can now see that the response that we get in our app.componentis of the type User. Now you can add all sorts of additional validations and modifications to the User.

Conclusion

In conclusion, I would like to point out that this approach is not always necessary, but it is very useful when it comes to complex applications which have a large number of entities and validations associated with each.

You can find the entire codebase here: https://github.com/40x/httpclient

Please leave comments and provide feedback :)

If you enjoyed this blog be sure to give it a few claps or follow me on LinkedIn


Published by HackerNoon on 2018/07/14