I'm writing an Angular 2 service in TypeScript that will make use of localstorage
. I want to inject a reference to the browser window
object into my service since I don't want to reference any global variables like Angular 1.x $window
.
How do I do that?
If you want to use angular services (and Http is an angular service) you must inject them as I told above as a constructor attribute to another service / component , which means if you want to use Http you need to have your service injectable. So the answer is no, you can't do it in a nice way.
@Inject() is a manual mechanism for letting Angular know that a parameter must be injected. It can be used like so: import { Component, Inject } from '@angular/core'; import { ChatWidget } from '../components/chat-widget';
You can inject an Angular service in a component, service, directive etc by specifying the service and its type in a component's constructor. Note that injecting a service through a class constructor is, in general, tree-shakable.
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
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With