16

I am using dot net core with angular 4 and webpack config.

When I am trying to get the window or document in a component or service, I am getting this error:

ReferenceError: document is not defined

ReferenceError: window is not defined

Here are the errors i am getting:

Microsoft.AspNetCore.NodeServices[0]
      ERROR { ReferenceError: window is not defined
          at _window (C:\gitRepose\AngularCore\FM\FMWebApp\FootballWebApp\ClientApp\dist\main-server.js:30801:12)

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
      An unhandled exception has occurred: window is not defined
      ReferenceError: window is not defined
    at _window (C:\gitRepose\AngularCore\FM\FMWebApp\FootballWebApp\ClientApp\dist\main-server.js:30801:12)

I am still new to the webpack stuff, anyone know how i can fix this? I need the window to handle when a window is resizing.

EDIT...

I managed to get this fixed by removing the pre render from the index.cshtml

i changed it from this:

<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>

to this:

<app>Loading...</app>

but now obviously pre rendering on server side won't be happening :/ thus it will slow the app boot up time, any ideas how I can fix this without loosing server side pre rendering?

Community
  • 1
  • 1
fattikus
  • 542
  • 1
  • 4
  • 15

8 Answers8

8

If you're using server-side rendering, you should remove all code using window or document that run in node because node doesn't have these variables (node only have global).

If you still want to use window or document in node env, you can try to use jsdom (https://github.com/tmpvar/jsdom).

Quoc-Anh Nguyen
  • 4,798
  • 1
  • 22
  • 34
  • Do you know how I should set JSDOM up in my webpack configuration? or do you have any helpful link? – fattikus Sep 25 '17 at 13:51
  • You don't need to add jsdom to webpack's config. You just need to require it in your node: https://github.com/tmpvar/jsdom – Quoc-Anh Nguyen Sep 25 '17 at 13:53
  • @fattikus You can read its docs because of how to use is depend on what you want. But in my optional, you don't need to use `window` in server-side rendering – Quoc-Anh Nguyen Oct 01 '17 at 16:00
4

If you want to use AOT, use dependency injection to mount window into your components. In short, write a service that can provide the window object:

import { Injectable } from '@angular/core';

function getWindow (): any {
    return window;
}

@Injectable()
export class WindowRefService {
    get nativeWindow (): any {
        return getWindow();
    }
}

More information here.

Gokhan Kurt
  • 8,239
  • 1
  • 27
  • 51
4

If you want a quick fix : put this code at the top of your typescript file :

 declare var window;
 declare var document;

But if you wanna do it properly :

 import { DOCUMENT } from '@angular/platform-browser';
 export const WINDOW           = new InjectionToken( 'WINDOW' );

 @Component()
 export class YourComponent{
          constructor(
              @Inject( WINDOW ) private window,
              @Inject( DOCUMENT ) private document){}

inside your module :

providers       : [
    {
        provide  : WINDOW,
        useValue : window
    }
],

This way you can override window and document in your tests and anywhere else.

Milad
  • 27,506
  • 11
  • 76
  • 85
3

wrap your code which depends on window like below

if (typeof window !== 'undefined') {
    // your client-only logic here like below
    alert(window.innerWidth);
}
cahit beyaz
  • 4,829
  • 1
  • 30
  • 25
3

Well i'm using angular 4 application and inject the window object using:

In Component constructor( @Inject('Window') private window: Window) { }

and In module: providers: [{ provide: 'Window', useValue: window }]

and then in the component function i used it like: this.window

Touqeer Shafi
  • 5,084
  • 3
  • 28
  • 45
3

In Server Side JavaScript is running in Node Environment which does not have window or document object. Window & Document object works when your javascript code executes in Browser Environment. So make sure window or document object related code does not execute on Server Side

You may use node-jsdom (https://www.npmjs.com/package/node-jsdom) if you really need to use window or document object. Just install

$ npm install node-jsdom 

Here (https://github.com/darrylwest/node-jsdom) you will get help on node-jsdom

Rabbani
  • 61
  • 6
1

Place your window. related code inside componentDidMount function.

0

In Index.html or Index.cshtml

Change From

<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>

To

<app asp-ng2-prerender-module="ClientApp/dist/main-server">Loading...</app>

If you are using angular4 in aspnetcore, It should work fine

Rahul Uttarkar
  • 3,367
  • 3
  • 35
  • 40