Angular 5 : Consuming RESTful Service with HttpClient and RxJS
Important announcement : We are moving all our content to new website - Witscad Courses . You can find the updated complete Angular course here - A Complete Angular Tutorial. Feel free to visit.
REST or HTTP based services are the primary requirements of single page applications to retrieve the data and gel into the web application. Angular offers its inbuilt http client service which wraps the major functions for requesting the data from server where REST service is hosted.Angular provides HttpClient for this purpose which is packaged under @angular/common/http. Before we can use HttpClient, we have to import HttpClientModule in our main application module.
import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {HttpClientModule} from '@angular/common/http'; @NgModule({ imports: [ BrowserModule, HttpClientModule, ], }) export class MyAppModule {}
RxJS
An Observable is a class provided by RxJs. To learn more about RxJS, please visit http://reactivex.io/rxjs/Observables are pretty much similar to promise or callbacks but the main advantage is they are lazy loaded. Observables will not be called till the time any subscriber invoked on it.
Feel free to play around at RxMarbles website http://rxmarbles.com to get to know how values are observed over time.
Building our example app
Let us start with an example. Here we are building a simple survey which will ask a question and user can choose from one of the four option. We will get our survey data from our Http service as JSON.Full working example is here - https://embed.plnkr.co/eKil3iBwhppDNtzqf2YH/
Create a survey interface
export interface ISurvey{ question:string; choices: string[]; }
Our Survey Data
Let's add couple of questions in our json survey data which we will request from our http service. You can add more later.[ { "question": "What is your favourite programming language?", "choices": ["Swift","Python","Objective-C","Ruby"] }, { "question": "What is your major learning source?", "choices": ["Books","Online Tutorials","Online Bootcamp courses"] } ]
Our Survey Service
We will now add our survey service class which will provide data interaction operations to our survey class. Now, to make survey service injectable we'll import Injectable from '@angular/core' and decorate our component with @Injectable().@Injectable() export class SurveyService { .. }
Injecting HttpClient into Survey service
Add http functionality by importing HttpClient from '@angular/common/http' and inject the HttpClient in our constructor:import {HttpClient, HttpErrorResponse } from '@angular/common/http' export class SurveyService { constructor(private _http:HttpClient){ .. }
Adding Observable method in Survey service
As discussed previously, we will add Rxjs Observables to work with Http services since we have values that will be received in some point of time. Observables works best in these scenarios.import {Observable} from 'rxjs/Observable'
import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/map';
getSurveyQuestion(): Observable<ISurvey[]>{ return this._http .get<ISurvey[]>('./src/survey.json') .do(data =>console.log('All : ' + JSON.stringify(data))) .catch(this.handleError); }
Injecting our Survey Service:
Now, as we have our service ready, we will inject it in our Survey class constructor:import {ISurvey} from './isurvey' import {SurveyService} from './survey.service'; export class Survey { MySurvey : ISurvey[] = []; constructor(private _surveyService: SurveyService){ ... } }
Calling our observable method from SurveyService
We can not call that in our constructor. Why?Just for the simple reason that we can not delay the construction of our component till the time we get our json data from the network.
So, where we will call this method?
Angular provides us with Lifecycle hooks. Read more here.. https://angularbytes.witspry.com/2017/09/angular-5-life-cycle-hooks.html
One of the lifecycle hook is ngOnInit(). After our component is constructed, ngOnInit() lifecycle hook is called. So, we will implement it and call our RESTful method within this lifecycle hook.
export class Survey implements OnInit{ MySurvey : ISurvey[] = []; constructor(private _surveyService: SurveyService){ } ngOnInit(){ this._surveyService.getSurveyQuestion().subscribe(data => { console.log(data); this.MySurvey = data; }, err => { console.log(err); }); } }
Finally, here is our template which will be rendered as soon as data gets populated in our ISurvey[] array.
Component({ selector: 'survey', template: `<div> <h2>Question : </h2> <div *ngIf="MySurvey && MySurvey.length"> <div *ngFor="let survey of MySurvey; let idx = index"><br/> <div>{{survey.question}}</div> <div *ngFor="let choice of survey.choices"> <input type="radio" name="radioGroup{{idx}}"/>{{choice}} </div> </div> </div> </div> ` }) export class Survey implements OnInit{ ... }
The RxJS Retry operator
If your want to retry your http requests on case you receives error in your http response, then there is a retry operator (provided by RxJs) that you can use to resubscribe to the observable to re-invoke it for a number of times.This following code will retry 3 times as http service continues to receive any http error.
import 'rxjs/add/operator/retry'; http .get('/api/questions') .retry(3) .subscribe(...);
You can go through the advance Http configuration and functions from the Angular's official documentation: https://angular.io/guide/http
Hey, that's pretty good three.
ReplyDeleteand exactly what i needed, thanks.
Thanks Yann! If you feel any content related to Angular that can be added, please provide your thoughts on this. Thanks Again!
DeleteNo probs. your guides are helping me.
DeleteThe thing is, I was tasked with finishing up an angular app back in january this year. which made me prime target to handle switching the app from angular 1 all the way to 5 in one go( I say "all the way", but it's not like it would make much sense to go for any of the versions that came in between ).
Frankly your "complete angular5 tutorial" is indeed pretty complete. At least for what I needed from purely Angular5.
Thanks to you I'm now mostly struggling with updating the Angular Material parts. I don't know if Material falls in your range of expertise, and maybe I just missed something big, but I find the documentation on it lacking a little.
I'm still a student btw, I have sort of a work-school scholarship.
The reason I'm telling you isn't just so we get to know each other better tho ;)
Point is, next semester, i believe we might well be working on Angular. or at least Javascript with the option of using Angular, so I probably will share this around to the other students. Just letting you know. I can't promise you that they will be all that talkative though, since we're french and they can't talk english as well as I do.
And thank *you* again c:
Really thanks again for your valuable comments. If you want to connect on facebook, this is my group where we full stack developers try to solve all development related queries.
ReplyDeletehttps://www.facebook.com/groups/fullstackdevelopersnetwork/
You can join this.
Also, Since you have mentioned, I will try to write on Angular Material soon covering its most of the aspects on Angular 5 with live example.
It will be great and will boost me to write more, if you share this website with your friends and colleagues. In any case, I will be happy to answer all queries here or in my Facebook group.
Thank You very much.
ReplyDeleteThis is very helpful, I'm migrating an Angularjs app to Angular5
Looking forward to the Angular Material article.
Thanks a lot Connie.! I am looking forward to bring more articles and even on Angular Material. Stay tuned.!
DeleteIf you like the articles, do share with your friends to support.
Please join my facebook group where I personally resolve various development queries - https://www.facebook.com/groups/fullstackdevelopersnetwork/
Hi,
ReplyDeleteGreat Article,
I am new to angular, how can we add custom header for every request, or whenever api call header will automatically attached with request, please suggest solution.
Hi Ahsan,
DeleteThanks a lot for the appreciation. I would like to write a new article on sending a custom header on every request. Meanwhile you can explore various options from this page - https://stackoverflow.com/questions/34464108/angular-set-headers-for-every-request
Thank you so much for such great material.
ReplyDeleteI'm literally new to angular and this material
is really helping out to take me towards professionalism.
Keep on writing Man...
Thank You!
Thanks a lot for these words. I am looking forward to write more and more around Angular. Stay tuned to AngularBytes :)
DeleteIf you like the articles, do share with your friends to support.
Please join my facebook group where I personally resolve various development queries - https://www.facebook.com/groups/fullstackdevelopersnetwork/
ReplyDeleteWell Said, you have furnished the right information that will be useful to anyone at all time. Thanks for sharing your Ideas.
Angularjs course in chennai
Hi Satya,
ReplyDeleteThanks for the article.
https://embed.plnkr.co/eKil3iBwhppDNtzqf2YH/
The plunker code is not working now. Any pointers to get it working
Error in Console:
Error {originalErr: Error, constructor: Object}
originalErr: Error
: "Error"
name: "Error"
This comment has been removed by a blog administrator.
ReplyDeleteImportant announcement : We are moving all our content to new website - Witscad Courses . You can find the updated complete Angular course here - A Complete Angular Tutorial. Feel free to visit.
ReplyDeleteVery interesting information, worth recommending. However, I recommend this: help with data analysis
ReplyDeleteI think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. https://catcherrors.com/repos/flutter/flutter
ReplyDelete