Adding Angular Material in ASP.NET Core Angular SPA template (Bonus : Animations)

If you are not familiar with ASP.NET Core SpaServices, take a look at this repository:

https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices

Lots of SPA templates (Angular, React, Vue, Aurelia etc.) are available in this repo that uses NodeServices for server side rendering. We will work with the AngularSpa template and add Angular Material in it.

To install the Spa templates via yeoman, first intall the template generator with the following command:

npm install -g generator-aspnetcore-spa@next

Create a directory where you will initialize the template using yeoman. Run this command on the root of your created directory:

yo aspnetcore-spa

To install Angular Material run the following command:

npm install --save @angular/material

When the installation is done, you will have to include the package (@angular/material) name in the vendor section of webpack.config.vendor.js file. Also you have to add a default Angular Material prebuilt theme to get rid of unwanted warning messages in the browser's console. Modify the vendor section by adding the following two lines:

"@angular/material",
"@angular/material/prebuilt-themes/deeppurple-amber.css"

N.B: I'm using the deeppurple-amber theme. There are three other themes available in the @angular/material/prebuilt-themes directory. Use one of your like.

Now, you have to run webpack passing in the vendor script (webpack.config.vendor.js) as configuration flag (--config). Run the following command:

webpack --config webpack.config.vendor.js

And you are good to go. Run the application and you should not face any issues.

Let's see how we can add a md-button in the counter.component.html file. To do that first you have to add the MdButtonModule from @angular/material pacakage. Open up the app.module.client.ts; import MdButtonModule and add it to the imports array like this,

/* Other import statements */
import { MdButtonModule } from '@angular/material';

@NgModule({
    bootstrap: sharedConfig.bootstrap,
    declarations: sharedConfig.declarations,
    imports: [
        /* Other import modules */
        MdButtonModule
    ],
    providers: [
        { provide: 'ORIGIN_URL', useValue: location.origin }
    ]
})
export class AppModule { }

Almost done! Now open up the counter.component.html under ClientApp/app/counter and change the counter button syntax to the following:

<button md-raised-button (click)="incrementCounter()">Increment</button>

If you made these changes while in debugging process then the project will automatically push the changes using webpack's hot module replacement feature and you will see something like this on the browser window:

Bonus: Adding Animation Module

Many people are having trouble working with the @angular/animation module and this is how you will apply hover animation on the Increment button:

Import the animation module (BrowserAnimationsModule) and add it to the imports array. Add it in the app.module.client.ts file.

/* Other import statements */
import { MdButtonModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
    bootstrap: sharedConfig.bootstrap,
    declarations: sharedConfig.declarations,
    imports: [
        /* Other importes modules */
        MdButtonModule,
        BrowserAnimationsModule
    ],
    providers: [
        { provide: 'ORIGIN_URL', useValue: location.origin }
    ]
})
export class AppModule { }

N.B: If you by chance add the @angular/platform-browser/animations module in the app.module.server.ts, you will get this 501 error message:

This is because you are using server side rendering (SSR) and in server-side Angular Universal doesn't let you access the document object of the browser.

Now that you have included the animation module let's use it in the counter.component.ts like the following:

import { Component } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations';

@Component({
    selector: 'counter',
    templateUrl: './counter.component.html',
    styles: [`
        .myButton {
            background-color: purple;
            color: white;
        }

        .myButton:hover {
            background-color: orange;
            color: white;
        }
    `],
    animations: [
        trigger('hoverAnimation', [
            transition(':enter', [   // :enter is alias to 'void => *'
                style({ opacity: 0 }),
                animate(250, style({ opacity: 1 }))
            ]),
            transition(':leave', [   // :leave is alias to '* => void'
                animate(100, style({ opacity: 0 }))
            ])
        ])
    ]
})
export class CounterComponent {
    public currentCount = 0;

    public incrementCounter() {
        this.currentCount++;
    }
}

Add the .myButton class and the hoverAnimation attribute to the Increment button like the following:

<button md-raised-button class="myButton" (click)="incrementCounter()" [@hoverAnimation]>Increment</button>

And you are done! Run the application and you should get some hover animation on your button like this:

https://github.com/fiyazbinhasan/AspNetCoreAngularSPAMaterial