The issue of 'window is undefined' arises when utilizing window as a useValue provider in Angular 4 with

When compiling an Angular 4.0.2 application ahead-of-time, and defining a provider using useValue

import { OpaqueToken, Provider } from '@angular/core';

export const windowToken = new OpaqueToken('window');
export const windowProvider = { provide: windowToken, useValue: window };

and then using it like this

@NgModule({ providers: [windowProvider], ... })
export class AppModule {}

the compilation completes without errors but results in window being undefined when trying to inject it in the constructor:

constructor(@Inject(windowToken) window) {
   window.navigator...
}

An error occurs during bootstrapping:

TypeError: Cannot read property 'navigator' of undefined

Upon examining the auto-generated app.module.ngfactory.js file, it becomes evident that window is indeed undefined:

...
import * as import39 from './window';
var AppModuleInjector = (function (_super) {
    ...
    AppModuleInjector.prototype.createInternal = function () {
        ...
        this._windowToken_26 = undefined;
        this._SomeService_27 = new import16.SomeService(this._windowToken_26);
    }
    AppModuleInjector.prototype.getInternal = function (token, notFoundResult) {
        ...
        if ((token === import39.windowToken)) {
            return this._windowToken_26;
        }
        ...

However, if the same service is used with useFactory, everything works fine:

export function windowFactory() {
  return window;
}
export const windowProvider = { provide: windowToken, useFactory: windowFactory };

What exactly causes the issue when using window as a useValue provider? Is it a common problem? Does this limitation apply to all global variables or all useValue providers?

Answer №1

Dealing with a similar issue involving SignalrWindow, I encountered an error that was strikingly similar to what was discussed.

Fortunately, I stumbled upon this informative article () and discovered some helpful comments at the end of it that guided me in resolving the problem.

In essence, the solution involved utilizing a factory method instead of a useValue within the providers. Although I'm unsure about the root cause of the issue, adopting this approach effectively addressed the ahead-of-time compilation problem.

Here are the steps to rectify the issue:

Create an exported function as follows:

export function windowFactory(): any {
    return window;
}

Subsequently, within the core module under @NgModule, you can implement the following configuration in the providers section:

...
providers: [
    { provide: SignalrWindow, useFactory: windowFactory }
]
...

You have the flexibility to alter the methods' names according to your preference (for instance, in your specific scenario):

export const windowProvider = { provide: windowToken, useFactory: windowFactory };

Answer №2

During the compilation process of Angular CLI, the code is analyzed statically to create a ngmodule.factory file. If the compiler encounters "useValue", it checks if a static value is present and includes it in the ngmodule.factory. Since this value is not available during compile time, the provider value remains undefined when injected into the constructor.

On the other hand, "useFactory" serves the same purpose for cases where the value is only known at runtime.

In your situation, "useValue" does not function as expected, but "useFactory" will produce the desired outcome.

To summarize: Use "useValue" when dealing with static values like constant strings or numbers during AOT compilation. For dynamic object/values calculated at runtime, opt for "useFactory".

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When running nodemon in an npm project without any arguments, it fails to execute the value specified in the "main" field of the package.json

My current npm project has the following folder structure: project ├── node_modules │ └── (node_modles folders) ├── server.js ├── index.js ├── index.html ├── package.json └── package-lock.json The JavaScr ...

Acquiring an icon of a program using its handle

I am looking for a way to extract a program's icon from its handle, which I acquired using User32.dll with EnumWindow/FindWindow. While I am aware of ExtractAssociatedIcon, it seems to work from a file instead of a handle. My question is how can I con ...

Transfer data in JSON format to the server using Ajax

Currently, I have an HTML form where I am in the process of creating a JSON object using JavaScript. Here is how it looks: var JSobObject= '{"name":"'+personObject.GetPersonName()+ '","about":"'+personObject.GetAbout()+ &ap ...

Tips for excluding empty strings from the total length calculation

Issue: My input fields should turn into green buttons once the correct syllables are inserted. However, the problem lies in the fact that it determines correctness based on the length of my JSON data compared to what the user inputs. Even when my array con ...

Angular6 dropdown menu malfunctioning---"The Angular6 dropdown menu is not functioning

I'm having an issue where clicking on a sidebar item does not open the menu as expected in my Angular 6 project. I'm unsure of how to troubleshoot and fix this problem. <li *ngIf="mUser.role.accountant !== true" class="nav-item dropdown" rout ...

Failed to download JSON file in Angular 2

I am trying to export a data table to a JSON file using the code below: import { ErrorHandler } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Component, Input } from '@angular/core&a ...

An issue has occurred while trying to execute the npm start command within PhpStorm

When I try to run npm start on Windows' command prompt, it works fine. However, I encounter errors when running it in the PhpStorm Terminal. You can see the errors here. Is this a result of them being different platforms or could it be related to som ...

What is the reason for the malfunction of this JavaScript code designed for a simple canvas operation?

I'm having trouble with the code below. It's supposed to display a black box on the screen, but for some reason it's not working properly. The page is titled Chatroom so at least that part seems to be correct... <html> <head> &l ...

Arranging a JSON array based on the numerical value within an object

I am interested in sorting an array from a json file based on distances calculated using the haversine library. The purpose is to find geolocations near a specified value and display the closest results first. function map(position){ var obj, ...

The functionality of hover effects and JavaScript animations/interactions seems to be disabled when using the <a> tag

I'm building a website for a soccer team and looking to incorporate a sliding image carousel. I've noticed that the arrow buttons (.prev or .next) are not responding when clicked or hovered over. The arrows should have a shadow effect on hover, ...

Utilize React's useRef with ChakraUI Toasts

Struggling to figure out what specific type I need to provide for React.useRef() when looking at the code snippet provided in the Chakra docs: function UpdatingToastExample() { const toast = useToast() const toastIdRef = React.useRef() function upda ...

Issues with Angular Material Pagination functionality may be causing unexpected behavior

I'm facing an issue with displaying data in an HTML table using an API. I've tried to implement pagination to show 3 or 6 rows per page, but it's not working as expected. Currently, all the data is being displayed without any pagination, whe ...

Displaying object properties within another object obtained from an API request in a React component

Dealing with API data can be tricky, especially when there are nested objects involved. I've encountered an error message stating 'undefined is not an object (evaluating 'coin.description.en')', as the description property of the c ...

Passing events from a grandchild component up to its grandparent component in VueJS 2.0

Vue.js 2.0 appears to have a limitation where events cannot be emitted directly from a grand child component to its grand parent. Vue.component('parent', { template: '<div>I am the parent - {{ action }} <child @eventtriggered="pe ...

Issue with nodes not holding position properly in d3 Force Directed Graph fixed

My approach involves setting the nodes as fixed: let link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) .enter().append("line") .attr("stroke-width", () => 4) let node = svg.append('g') .attr("c ...

Validating Forms in TypeScript

Currently in the process of learning Angular 10, but encountering a challenge I have an HTML document that validates a form group in my component. When I set a value for a textbox from my component, the value is displayed correctly, but my submit button c ...

I am facing an issue where the jQuery method does not work when an AJAX function is called within another AJAX function

There seems to be an error showing up in the console. XMLHttpRequest has finished loading: POST "http://localhost/redono/Redono-ChurchAdmin/code/churchprofile/edit_password". I am currently working on implementing a change password method. $.ajax({ ...

Strangely behaving data binding when using socket.io

Recently, I've been experiencing some strange behavior while developing a socket.io app with Angular 2 on the frontend. This unusual issue seems to be related to the interaction between Angular 2 and socket.io, as I have never encountered anything lik ...

Exploring Highcharts Pie Chart with AJAX for Real-time Data Updates

Looking for some guidance with implementing AJAX in my code to make my chart dynamic based on data from the database. Although the code is error-free, the chart is not refreshing automatically. Any help, comments, or suggestions would be greatly appreciate ...

I keep encountering a Vuex error stating ReferenceError is not defined. What is the correct way to properly set a value

I have a question regarding Vuex. How can I properly set a value for signupError in my function signUp()? I attempted using the following code snippets: commit(signupError, null) and $state.commit(signupError, null) , but I encountered an error stating "R ...