Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject window into a service?

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?

like image 920
lokanx Avatar asked Dec 09 '15 11:12

lokanx


People also ask

Can we use service without injectable?

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.

What is @inject in Angular?

@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'; ​

Can we inject Service inside service in Angular?

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.


2 Answers

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

like image 67
elwyn Avatar answered Oct 30 '22 13:10

elwyn


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);   }  } 
like image 35
Alex Nikulin Avatar answered Oct 30 '22 13:10

Alex Nikulin