Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular4 document and window are undefined

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?

like image 556
fattikus Avatar asked Sep 21 '17 09:09

fattikus


7 Answers

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).

like image 192
Quoc-Anh Nguyen Avatar answered Oct 30 '22 15:10

Quoc-Anh Nguyen


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.

like image 30
Gokhan Kurt Avatar answered Oct 30 '22 14:10

Gokhan Kurt


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.

like image 4
Milad Avatar answered Oct 30 '22 14:10

Milad


wrap your code which depends on window like below

if (typeof window !== 'undefined') {
    // your client-only logic here like below
    alert(window.innerWidth);
}
like image 3
cahit beyaz Avatar answered Oct 30 '22 13:10

cahit beyaz


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

like image 3
Rabbani Avatar answered Oct 30 '22 15:10

Rabbani


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

like image 3
Touqeer Shafi Avatar answered Oct 30 '22 13:10

Touqeer Shafi


Place your window. related code inside componentDidMount function.

like image 1
user8335505 Avatar answered Oct 30 '22 13:10

user8335505