Javascriptservices: Adding angular material 2 to a project

Created on 1 Dec 2016  路  8Comments  路  Source: aspnet/JavaScriptServices

Hi,

I've followed the instructions here:
https://github.com/angular/material2/blob/master/GETTING_STARTED.md
minus the angular-cli parts:

npm install --save @angular/material
npm install --save hammerjs 
npm install --save-dev @types/hammerjs

and added this code to my app.module.ts file:

import { UniversalModule } from 'angular2-universal';
import 'hammerjs';
.
.
.
@NgModule({
    bootstrap: [ AppComponent ],
    declarations: [
        AppComponent,
        NavMenuComponent,
        CounterComponent,
        FetchDataComponent,
        HomeComponent,
        MaterialModule
    ],
    imports: [
        UniversalModule, // Must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too.
        RouterModule.forRoot([
            { path: '', redirectTo: 'home', pathMatch: 'full' },
            { path: 'home', component: HomeComponent },
            { path: 'counter', component: CounterComponent },
            { path: 'fetch-data', component: FetchDataComponent },
            { path: '**', redirectTo: 'home' }
        ])
    ]
})
export class AppModule {
}

But now I'm getting this error:

An unhandled exception occurred while processing the request.
Exception: Call to Node module failed with error: Prerendering failed because of error: ReferenceError: window is not defined

A lot more is written in the error but the window is not defined part is making me somewhat uncomfortable.

I'm new to Angular Universal but I'm guessing the code is trying to run on the server and there's no window there.

I'm developing a new platform for our existing startup and time is of the essence 馃槄 should I use Angular Universal? Is it ready for production?

Thank you!

Most helpful comment

So what you're saying is that every library that I would want to use for an Universal project will have to support Universal?

Every library that runs on the server needs not to rely on browser-specific APIs such as window. Most libraries that target Angular 2 are built with this in mind, but Material is a notable exception unfortunately.

I always thought that server-side prerendering is running in some headless browser so objects like window and document will be seamlessly supported.

If you were determined, you most likely could make that work, e.g., using jsdom to supply the APIs like window inside a Node environment. The performance wouldn't be as good, because emulating the DOM (etc.) involves running quite a lot of code.

Is that the case for Universal apps that are written with NodeJs as well?

Yes, it's doing exactly the same thing at runtime.

All 8 comments

Here's the issue: https://github.com/angular/material2/issues/308

Yes, Material2 doesn't support Angular Universal (or vice-versa, depending on how you want to look at it).

For now you either need to use something else instead of Material2, or disable server-side prerendering. Sorry!

Thank you @SteveSandersonMS !

So what you're saying is that every library that I would want to use for an Universal project will have to support Universal?

I always thought that server-side prerendering is running in some headless browser so objects like window and document will be seamlessly supported.

Is that the case for Universal apps that are written with NodeJs as well?

Material will work with Universal but they're still in Alpha, but they will focus on making it Universal very soon.

Also, yes, one of the paradigms when dealing with SSR is that you have to think about both platforms, so make sure to stay away from jQuery, and other libraries that use the window/document/etc. luckily you won't need those, and there's a vast ecosystem of ng2 libraries made with Universal in mind, so you won't have any problems!

If you absolutely need to access the window/etc there are ways around it. Check out our list of Universal Gotchas for a few things to keep in mind.

https://github.com/angular/universal#universal-gotchas

For now if you want Material, just remove the asp-prerendering tag in your index.cshtml so you can get started building your app, soon we will have Material fixed!

So what you're saying is that every library that I would want to use for an Universal project will have to support Universal?

Every library that runs on the server needs not to rely on browser-specific APIs such as window. Most libraries that target Angular 2 are built with this in mind, but Material is a notable exception unfortunately.

I always thought that server-side prerendering is running in some headless browser so objects like window and document will be seamlessly supported.

If you were determined, you most likely could make that work, e.g., using jsdom to supply the APIs like window inside a Node environment. The performance wouldn't be as good, because emulating the DOM (etc.) involves running quite a lot of code.

Is that the case for Universal apps that are written with NodeJs as well?

Yes, it's doing exactly the same thing at runtime.

I see,

I think I'll try to remove the asp-prerendering tag from the index.cshtml or just not use material yet.

Know that I strongly believe in what's your doing, I'm sure that SSR is the future.

Thank you so match @SteveSandersonMS and @MarkPieszak for making it a reality!

Has anyone disabled server-side prerendering to get material working as suggested here, but then had issues rendering some of the material controls, such as md-checkbox, md-radio-button, md-progress-bar? Any suggestions would be greatly appreciated!
material rendering issue

peterdobson Did you set some of the angular material themes?
https://github.com/angular/material2/blob/master/docs/theming.md
Just include like this to your index file:

Thanks for the suggestion dimonzav. I was using a custom theme as described in the link you posted and some controls were rending OK, but not all. I've managed to workaround this by using copy of one of the @angular\material\core\theming\prebuilt......css files referenced in _Layout.cshtml, in addition to the custom app-theme.scss referenced in app.component.ts. This feels like a hack but it will do for the time being!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

harsimranb picture harsimranb  路  3Comments

natemcmaster picture natemcmaster  路  4Comments

LovedByTheLord picture LovedByTheLord  路  3Comments

dantheman999301 picture dantheman999301  路  4Comments

caesay picture caesay  路  3Comments