Click here to Skip to main content
15,886,806 members
Articles / Web Development / ASP.NET
Tip/Trick

Upgrade to Angular 5 and HttpClient

Rate me:
Please Sign up or sign in to vote.
4.75/5 (4 votes)
26 Dec 2017CPOL3 min read 71.2K   7   4
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:

JavaScript
"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

JavaScript
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:

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

with:

JavaScript
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:

JavaScript
{
    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:

JavaScript
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:

JavaScript
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:

JavaScript
@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:

JavaScript
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:

JavaScript
@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)


Written By
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.

Comments and Discussions

 
Questionhttp gone in Angular 8 finally. Pin
Zijian11-Aug-19 18:53
Zijian11-Aug-19 18:53 
QuestionAngular 6 Tutorial With Example Using Angular CLI Pin
KrunalLathiya17-Jun-18 8:44
KrunalLathiya17-Jun-18 8:44 
QuestionI need som help with this error Pin
pronick3-Dec-17 23:29
pronick3-Dec-17 23:29 
AnswerRe: I need som help with this error Pin
Zijian5-Dec-17 17:29
Zijian5-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.