How to inject window into a service? How to inject window into a service? angular angular

How to inject window into a service?


This is working for me currently (2018-03, angular 5.2 with AoT, tested in angular-cli and a custom webpack build):

First, create an injectable service that provides a reference to window:

import { Injectable } from '@angular/core';// This interface is optional, showing how you can add strong typings for custom globals.// Just use "Window" as the type if you don't have custom global stuffexport interface ICustomWindow extends Window {    __custom_global_stuff: string;}function getWindow (): any {    return window;}@Injectable()export class WindowRefService {    get nativeWindow (): ICustomWindow {        return getWindow();    }}

Now, register that service with your root AppModule so it can be injected everywhere:

import { WindowRefService } from './window-ref.service';@NgModule({          providers: [    WindowRefService   ],  ...})export class AppModule {}

and then later on where you need to inject window:

import { Component} from '@angular/core';import { WindowRefService, ICustomWindow } from './window-ref.service';@Component({ ... })export default class MyCoolComponent {    private _window: ICustomWindow;    constructor (        windowRef: WindowRefService    ) {        this._window = windowRef.nativeWindow;    }    public doThing (): void {        let foo = this._window.XMLHttpRequest;        let bar = this._window.__custom_global_stuff;    }...

You may also wish to add nativeDocument and other globals to this service in a similar way if you use these in your application.


edit:Updated with Truchainz suggestion.edit2:Updated for angular 2.1.2edit3:Added AoT notesedit4:Adding any type workaround noteedit5: Updated solution to use a WindowRefService which fixes an error I was getting when using previous solution with a different buildedit6: adding example custom Window typing


With the release of angular 2.0.0-rc.5 NgModule was introduced. The previous solution stopped working for me. This is what I did to fix it:

app.module.ts:

@NgModule({          providers: [    { provide: 'Window',  useValue: window }  ],  declarations: [...],  imports: [...]})export class AppModule {}

In some component:

import { Component, Inject } from '@angular/core';@Component({...})export class MyComponent {    constructor (@Inject('Window') window: Window) {}}

You could also use an OpaqueToken instead of the string 'Window'

Edit:

The AppModule is used to bootstrap your application in main.ts like this:

import { platformBrowserDynamic  } from '@angular/platform-browser-dynamic';import { AppModule } from './app/app.module';platformBrowserDynamic().bootstrapModule(AppModule)

For more information about NgModule read the Angular 2 documentation: https://angular.io/docs/ts/latest/guide/ngmodule.html


You can get window from injected document.

import { Inject } from '@angular/core';import { DOCUMENT } from '@angular/common';export class MyClass {  private window: Window;  constructor(@Inject(DOCUMENT) private document: Document) {     this.window = this.document.defaultView;  }  check() {    console.log(this.document);    console.log(this.window);  }}