Click here to Skip to main content
13,628,655 members
Click here to Skip to main content
Add your own
alternative version

Stats

45.9K views
6 bookmarked
Posted 11 Nov 2017
Licenced CPOL

Upgrade to Angular 5 and HttpClient

, 26 Dec 2017
Rate this:
Please Sign up or sign in to vote.
Upgrade to Angular 5 and HttpClient while Http is deprecated in NG5

Introduction

If you have applications built on Angular 2 or 4, moving to Angular 5 released on 1st November 2017 (2nd November AEST +10) is seamless. Your applications will enjoy most good things of Angular 5 right away.

HttpClient was introduced in Angular 4.3, and according to the ChangeLog of Angular at section "5.0.0 pentagonal-donut (2017-11-01)":

http: deprecate @angular/http in favor of @angular/common/http (#18906) (72c7b6e)

Surely, your existing codebase with the Http service is still working fine with next few releases of Angular, until the Angular team decides to remove @angular/http.

If you (team) have some time slots to do maintenance / refactoring works, it may be time to migrate to HttpClient@angular/common/http.

Remarks

  • If you are using Angular Material 2 Beta 12, you may have to be careful, as reported here. The good thing is, Material2 5.0.0-rc0 cesium-cephalopod (2017-11-06) had the problem fixed, and is also using HttpClient.

Upgrade

Step 0: Update NG modules in node_modules

In package.json, you should have the following or alike:

"dependencies": {
   "@angular/animations": "^5.0.0",
   "@angular/cdk": "^2.0.0-beta.12",
   "@angular/common": "^5.0.0",
   "@angular/compiler": "^5.0.0",
   "@angular/compiler-cli": "^5.0.0",
   "@angular/core": "^5.0.0",
   "@angular/forms": "^5.0.0",
   <s>"@angular/http": "^5.0.0",</s>
   "@angular/platform-browser": "^5.0.0",
   "@angular/platform-browser-dynamic": "^5.0.0",
   "@angular/platform-server": "^5.0.0",
   "@angular/router": "^5.0.0",

Delete the whole node_moodules folder, and run npm install.

Noted that the package for the Http service may be removed, though leaving it there does not harm. Also, if you have other 3rd party NG2 components that depend on the Http service, you may still need the deprecated Http service coexisting with the HttpClient service before the vendors could provide upgrades.

Remarks

You may have your own favorite update methods, then just go ahead.

Step 1: Refine systemjs.config.js

map: {
    app: 'app',
    // angular bundles
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic':
    'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
    '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
    '@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
    '@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
    '@angular/platform-browser/animations':
    'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',

    '@angular/cdk': 'npm:@angular/cdk/bundles/cdk.umd.js',
    '@angular/cdk/a11y': 'npm:@angular/cdk/bundles/cdk-a11y.umd.js',
    '@angular/cdk/bidi': 'npm:@angular/cdk/bundles/cdk-bidi.umd.js',
    '@angular/cdk/coercion': 'npm:@angular/cdk/bundles/cdk-coercion.umd.js',
    '@angular/cdk/collections': 'npm:@angular/cdk/bundles/cdk-collections.umd.js',
    '@angular/cdk/keycodes': 'npm:@angular/cdk/bundles/cdk-keycodes.umd.js',
    '@angular/cdk/observers': 'npm:@angular/cdk/bundles/cdk-observers.umd.js',
    '@angular/cdk/overlay': 'npm:@angular/cdk/bundles/cdk-overlay.umd.js',
    '@angular/cdk/platform': 'npm:@angular/cdk/bundles/cdk-platform.umd.js',
    '@angular/cdk/portal': 'npm:@angular/cdk/bundles/cdk-portal.umd.js',
    '@angular/cdk/rxjs': 'npm:@angular/cdk/bundles/cdk-rxjs.umd.js',
    '@angular/cdk/scrolling': 'npm:@angular/cdk/bundles/cdk-scrolling.umd.js',
    '@angular/cdk/stepper': 'npm:@angular/cdk/bundles/cdk-stepper.umd.js',
    '@angular/cdk/table': 'npm:@angular/cdk/bundles/cdk-table.umd.js',

    'tslib': 'npm:tslib/tslib.js',
    // other libraries
    'rxjs': 'npm:rxjs',
    //temp fix according to https://github.com/ReactiveX/rxjs/issues/2971
    'rxjs/operators': 'npm:rxjs/operators/index.js'

Particularly, add '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js' and 'tslib': 'npm:tslib/tslib.js', and optionally remove the mapping for '@angular/http'.

Step 2: Replace All Http Declarations with HttpClient

In each xxx.module.ts,

Replacement 1

Replace:

import { HttpModule, Http, ... } from '@angular/http'

with:

import { HttpClientModule, HttpClient, ... } from '@angular/common/http'

And in the imports section of @NgModule, replace HttpModule with HttpClientModule.

Hints

Make sure you search from @angular/http in every TS/JS files. Even if your app code is not using the import, the import may still try to download the js lib, and give you some strange 404 error in browser's console.

Replacement 2

In Angular 4.3 with the Http service, you may have to provide the following in the providers section of app.module.ts:

{
    provide: Http,
    useFactory: httpFactory,
    deps: [XHRBackend, RequestOptions]
},

In Angular 5 with the HttpClient service, this is not needed. So, simply remove it without providing HttpClient explicitly for DI.

Replacement 3

Comparing with Http, HttpClient provides high level abstractions for application programming.

With Http, your app code is typically like:

http.get(this.baseUri + 'api/Entities'+id)
.map(response=> response.json())
.subscribe(
    data=>{
       ....
    },
    error=>{
    ....
    });

The data type of "data" is weak.

With HttpClient, your app code will be like:

httpClient.get<Entity>(this.baseUri + 'api/Entities'+id)
.subscribe(
    data=>{
       ....
    },
    error=>{
       ....
    });

The data type of "data" is strong with Observable<Entity>.

Depending on how you had deserialized the JSON data, you may have a lot of replacements to do.

Points of Interest

If you have been using WebApiClientGen for your ASP.NET WebApi + Angular2 solution, you don't need to do the step of replacement 3, since WebApiClientGen had already supported this kind of app code since Angular 2 as HttpClient supports since Angular 4.3.

With the Http service, the generated client API is like this:

@Injectable()
export class Entities {
    constructor(@Inject('baseUri') private baseUri: string = location.protocol + '//' +
    location.hostname + (location.port ? ':' + location.port : '') + '/', private http: Http){
    }

    /**
     * Get a person
     * so to know the person
     * GET api/Entities/{id}
     * @param {number} id unique id of that guy
     * @return {DemoWebApi_DemoData_Client.Person} person in db
     */
    getPerson(id: number): Observable<DemoWebApi_DemoData_Client.Person>{
        return this.http.get(this.baseUri + 'api/Entities/'+id).map(response=> response.json());
    }

The app code is like this:

entitiesService.getPerson(1001)
.subscribe(
data=>
{ ....
},
error=>{ .
...
});

The data type of "data" had already been strong with Observable<DemoWebApi_DemoData_Client.Person>.

With the HttpClient service, the client API generated by WebApiClientGen v2.3 is like this:

@Injectable()
export class Entities {
    constructor(@Inject('baseUri') private baseUri: string = location.protocol + '//' +
    location.hostname + (location.port ? ':' + location.port : '') + '/', private http: HttpClient){
    }

    /**
     * Get a person
     * so to know the person
     * GET api/Entities/{id}
     * @param {number} id unique id of that guy
     * @return {DemoWebApi_DemoData_Client.Person} person in db
     */
    getPerson(id: number): Observable<DemoWebApi_DemoData_Client.Person>{
        return this.http.get<DemoWebApi_DemoData_Client.Person>(this.baseUri + 'api/Entities/'+id);
    }

So your app code could remain the same, because the interface getPerson(id: number): Observable<DemoWebApi_DemoData_Client.Person> remains the same.

For more details of using WebApiClientGen for Angular2, please check:

If you have been doing Web programming using jQuery and WebApiClientGen, you may also welcome the change to HttpClient, since in the generated client API codes for jQuery, the helper class is also named as "HttpClient". And in programming .NET client, the common helper class in the last few years is System.Net.Http.HttpClient. So you have 3 frameworks of Web client programming share the same name for HTTP client helper class.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Zijian
Software Developer
Australia Australia
I started my IT career in programming on different embedded devices since 1992, such as credit card readers, smart card readers and Palm Pilot.

Since 2000, I have mostly been developing business applications on Windows platforms while also developing some tools for myself and developers around the world, so we developers could focus more on delivering business values rather than repetitive tasks of handling technical details.

Beside technical works, I enjoy reading literatures, playing balls, cooking and gardening.

You may also be interested in...

Comments and Discussions

 
QuestionAngular 6 Tutorial With Example Using Angular CLI Pin
KrunalLathiya17-Jun-18 8:44
memberKrunalLathiya17-Jun-18 8:44 
QuestionI need som help with this error Pin
pronick3-Dec-17 23:29
memberpronick3-Dec-17 23:29 
AnswerRe: I need som help with this error Pin
Zijian5-Dec-17 17:29
memberZijian5-Dec-17 17:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02-2016 | 2.8.180712.1 | Last Updated 26 Dec 2017
Article Copyright 2017 by Zijian
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid