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 stuff
export 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.2
edit3:
Added AoT notes
edit4:
Adding any type workaround note
edit5: Updated solution to use a WindowRefService which fixes an error I was getting when using previous solution with a different build
edit6: adding example custom Window typing

Leave a Comment