Upgrade Angular 4 app to Angular 5 with Visual Studio 2017

Upgrade Angular 4 app to Angular 5 with Visual Studio 2017

Last month, Angular 5 was released with some code breaking changes. You can refer to this post for the list of changes. I was playing with Angular 5 and as part of this learning process; I thought of upgrading one of my previously created Angular 4 app to Angular 5. You can read my post about creating an Angular 4 application with Visual Studio 2017. This post talks about how to upgrade Angular 4 app to Angular 5 with Visual Studio 2017. The steps given in this post are applicable for Angular 4 apps created using Visual Studio 2017, but some of these steps will also apply to Angular 4 apps created using other ways.

Upgrade Angular 4 app to Angular 5

Configuring Angular with the Visual Studio was never straightforward until a few Angular ready templates introduced in Visual Studio. Similarly, the whole upgrade process also gives the same experience. It is not straightforward and time-consuming as Angular 5 has some code breaking changes. Let’s see this step-by-step process.

  • First, close all instances of Visual Studio 2017 as in my case the Angular package upgrade didn’t work when the VS was running. NPM could not upgrade the packages. So I suggest you to close VS instances.
  • Open PowerShell (Make sure to run it as Administrator). You can also use Node.js command prompt. I first tried with Node.js command prompt, but the packages were not updated in VS 2017. Then, I tried with PowerShell and things worked.
  • Browse to the location of the project and run dir command. You should see package.json file present in the output listing.
  • Update the Angular packages using the following commands.
    • npm install -g npm-check-updates
    • and ncu -u

    If you get any error while running these commands, update your node and npm version. You can follow the instructions given in this post to upgrade node and npm.

    You should see all the Angular packages are upgraded to Angular 5.

    Angular 5 Package json

  • Open your Angular 4 project in Visual Studio 2017 and go to Dependencies-> npm to check the Angular version. The packages should point to Angular 5.

    Angular 5 package updated in Visual studio 2017

    If it is still pointing to Angular 4, then delete the package-lock.json and follow the above-given steps again.

  • As you know, Webpack is used as module bundler by Visual Studio. Webpack uses AotPlugin to compile the Angular 4 apps, now Webpack no longer uses Aotplugin for Angular 5. It now uses AngularCompilerPlugin. You can read more about this here.

    So open webpack.config.js and replace all occurrences of AotPlugin with AngularCompilerPlugin.

  • Open ClientApp/boot.server.ts file and replace the following line of code (line no.22).
    const zone = moduleRef.injector.get(NgZone);

    with,

    const zone: NgZone = moduleRef.injector.get(NgZone);
  • Switch from Http Service to HttpClient Service. In Angular version 4.3 HttpClient was shipped in @angular/common as a smaller, easier, and more powerful way to make web requests in Angular. The new HttpClient has gotten some great praise from developers, so HttpClient is recommended by the Angular team for all applications, and @angular/http library is deprecated. To update to HttpClient, you’ll need to make the following changes:
    • Replace HttpModule with HttpClientModule from @angular/common/http in each of the modules.
    • Inject the HttpClient service.
    • Remove any map(res => res.json()) calls.

    The fetch data component uses HttpModule. It is located at “ClientApp/app/components/fetchdata”. Open the file and replace it with HttpClientModule. The following changes need to be done in the fetchdatacomponent.ts file,
    Replace All Http Declarations with HttpClient,

    import { Http } from '@angular/http';
    

    with,

    import { HttpClient } from '@angular/common/http'; 
    

    HttpClient provides high-level abstractions for application programming. With Http, the fetch data service code is like:

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
            this.forecasts = result.json() as WeatherForecast[];
        }, error => console.error(error));
    }
    

    Inject HttpClient in constructor and app code will be like:

    constructor(httpClient: HttpClient, @Inject('BASE_URL') baseUrl: string) {
        httpClient.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
            this.forecasts = result;
        }, error => console.error(error));
    }
    

    In the earlier post creating an Angular 4 application with Visual Studio 2017, I extended the fetch data component service to add a summary filter. So based on the same example, the updated code for fetchdatacomponent.ts will be like:

    import { Component, Inject } from '@angular/core';
    import { HttpClient } from '@angular/common/http'; 
    
    @Component({
        selector: 'fetchdata',
        templateUrl: './fetchdata.component.html'
    })
    export class FetchDataComponent {
        public forecasts: WeatherForecast[];
        public cacheForecasts: WeatherForecast[];
        public summaries: any[];
    
        constructor(httpClient: HttpClient, @Inject('BASE_URL') baseUrl: string) {
            httpClient.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
                this.forecasts = result;
                this.cacheForecasts = this.forecasts;
            }, error => console.error(error));
            httpClient.get<any[]>(baseUrl + 'api/SampleData/GetSummaries').subscribe(result => {
                this.summaries = result;
            }, error => console.error(error));
        }
    
        filterForeCasts(filterVal: any) {
            if (filterVal == "0")
                this.forecasts = this.cacheForecasts;
            else
            this.forecasts = this.cacheForecasts.filter((item) => item.summary == filterVal);
        }
    }
    
    interface WeatherForecast {
        dateFormatted: string;
        temperatureC: number;
        temperatureF: number;
        summary: string;
    }
    
    interface Summary {
        name: string;
    }
    
  • Replace HttpModule with HttpClientModule in app.module.shared.ts file.
  • Finally, change the following line of code in file Views/Home/Index.cshtml
    <app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>

    To,

    <app>Loading...</app>

That’s it. We are done with all the changes required to upgrade the Angular 4 app to Angular 5. We can now run the app to see Angular 5 app in action. You may see the following exception in the browser.

“NodeInvocationException: No provider for PlatformRef!”
To fix this issue, update the webpack to the latest version. Execute the following command in PowerShell to update webpack,

npm install --save-dev @ngtools/[email protected]

Build the app and run again. You should see app running in the browser. You can verify the Angular version by visiting counter component.

Angular 5 running app running in the browser

You can find the source code here at Github.

Reference post:

Summary

To conclude, this post takes you through a detailed guide for upgrading Angular 4 app created using Visual Studio 2017 to Angular 5. The main changes are with respect to upgrading Angular packages, changing Angular compiler plugin used by webpack and switching from Http to HttpClient module. The whole process is quite time-consuming and not documented anywhere. It would be ideal to have an automatic upgrade and an option to choose the Angular version while creating the project in Visual Studio to avoid burning the midnight oil.

Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

PS: If you found this content valuable and want to return the favour, then
Buy Me A Coffee

7 thoughts on “Upgrade Angular 4 app to Angular 5 with Visual Studio 2017

  1. Good Job!

    Looks like you and I have been playing with the same tools i.e. .Net Core and Angular in 2017.

    Well, I recently solved this problem, and I had to use Node v9 and latest NPM to upgrade to Angular5, because somehow Node v5 or v7 were not updating the Angular’s packages to v5. Well, thanks again. Great Post indeed!

  2. HI Well Done !!!
    You have explained it clearly to the point. I have an issue when follow the steps

    npm install –save-dev @ngtools/[email protected]
    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modulesfsevents):
    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {“os”:”darwin”,”arch”:”any”} (current: {“os”:”win32″,”arch”:”x64″})

    any Idea?

    1. Chanuri,

      Thanks for the appreciation. I am glad it helped you..

      Well I am also getting the same warning. You can ignore this warning. As you are using Windows os and fs-events is required on macOS. So that’s ok.

  3. I am not finding the package-lock.json file. The package.json file points to Angular 5.2.1 but when I open the dependencies folder the node packages are still pointing to 4.2.5. Any help would be appreciated.

    1. The package-lock.json file will be visible only when you click show all files option in solution explorer. It is hidden by default. I also faced the similar problem but deleting the lock file helped me to fix this issue.

  4. Thank you for this very helpful article.
    I already had most of this figured out and the debug build works but now the release/prod build fails at webpack:

    “node node_modules/webpack/bin/webpack.js –env.prod”:

    ERROR in ./ClientApp/boot.browser.ts
    Module not found(0,0): Error : Can’t resolve ‘./app/app.module.browser.ngfactory’ in ‘\ClientApp’
    @ ./ClientApp/boot.browser.ts 8:0-74

    There are a lot of similar errors online but their solution didn’t work for me.

Leave a Reply

Your email address will not be published. Required fields are marked *

three × 3 =