Config service injection resulted in an undefined configuration

I have been working on resolving an issue that I previously posted about. Despite not fixing it yet, I have made some discoveries that might help someone assist me.

Here is the setup in detail:
app-config.json (/src/assets/):

{
  "apiUrl": "localhost:8080"
}

app-config.service.ts (/src/app/):

import {Injectable, Injector} from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class AppConfigService {

  private appConfig: any;

  constructor (private injector: Injector) { }

  loadAppConfig() {
    let http = this.injector.get(HttpClient);

    return http.get('/assets/app-config.json')
      .toPromise()
      .then(data => {
        this.appConfig = data;
      })
  }

  get config() {
    return this.appConfig;
  }

}

app.module.ts (/src/app/):

import {APP_INITIALIZER, NgModule} from '@angular/core';
import {HttpClientModule} from '@angular/common/http';
import {AppConfigService} from './app-config.service';
import {CometdService} from './cometd/cometd.service';

const appInitializerFn = (appConfig: AppConfigService) => {
  return () => {
    return appConfig.loadAppConfig();
  }
};

@NgModule({
...
  providers: [HttpClientModule,
    AppConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: appInitializerFn,
      multi: true,
      deps: [AppConfigService]
    }]
})

export class AppModule {
  constructor(cometdService: CometdService) {}
}

cometd.service.ts (/src/app/cometd/):

import {Injectable, OnDestroy} from '@angular/core';
import {Store} from '@ngrx/store';
import * as fromRoot from '../reducers';
import {AppConfigService} from '../app-config.service';

export interface CometDExtended extends cometlib.CometD {
  websocketEnabled: boolean;
}

@Injectable({
  providedIn: 'root'
})
export class CometdService implements OnDestroy {

  protected cometd: CometDExtended = new cometlib.CometD() as CometDExtended;

  private subscriptions: cometlib.SubscriptionHandle[] = [];

  constructor(private environment: AppConfigService, private store: Store<fromRoot.State>) {
    let config = environment.config;
    let apiUrl = environment.config.apiUrl;
    
    this.cometd.configure('http://localhost:8080/cometd');
    this.startConnection();
  }
...
}
  • The problem occurs with various services, not just CometD.
  • The data in app-config.service.ts is retrieved correctly, as loadAppConfig() returns { "apiUrl": "localhost:8080" }.
  • The injected environment (AppConfigService) is defined as type Object.
  • environment.config is undefined, resulting in an error when trying to access environment.config.apiUrl: "TypeError: Cannot read properties of undefined (reading 'apiUrl')".

Answer №1

AppConfigService is typically not required in the providers array because specifying providedIn: 'root' automatically makes it accessible throughout the application.

If you choose to provide the service in different ways, there may be multiple instances created: one will be loaded while others may not be utilized.

If you are still facing issues, consider setting a breakpoint to verify if other services are being initialized prior to completion of initialization process. It is recommended to avoid making async calls in the CometdService constructor for cleaner execution.

Answer №2

Well, it didn't take long after I posted the question for me to stumble upon a resolution. It turns out that due to loadAppConfig() being asynchronous, there was a possibility of accessing environment.config before the promise had been fulfilled. By modifying the constructor as follows:

this.environment.loadAppConfig().then(() => {
let config = environment.config
...
});

I managed to successfully resolve the issue.

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

JavaScript code using jQuery's ajax method is sending a request to a PHP server, but

Attempting to utilize jQuery ajax for PHP call and JSON return. The test is quite simple, but only receiving an empty object in response. No PHP errors appearing in the LOG File. jqXHR is recognized as an object with 'alert', yet not displayin ...

What are the standard browser values for HTML elements like TABLE, TR, and TD, and how can you reset styles to their default settings?

It's common knowledge that each browser has its own default values for HTML elements. But what happens when we want to override specific styles set by CSS and revert back to the default browser style? For instance, if all TRs have a height value of 5 ...

What is the best way to conduct end-to-end testing on an Amazon Linux AMI?

Running end to end tests using Protractor has been smooth in Chrome and Firefox on Ubuntu. However, I encountered issues with PhantomJS as it could not locate the elements. My Angular version is v1.2.15. My aim is to test on an Amazon Linux AMI, so either ...

The Angular JS Factory fails to send data back to the controller

When I call the method getPopularMovies in my factory using the controller, it returns undefined. I'm not sure what mistake I've made here. Please help me figure it out. My Factory angular.module('ngMovies').factory('moviesFactor ...

How to navigate through list items in React without triggering a re-render

Currently, I am in the process of learning React. Let's consider a scenario where I have a component called ListContainer that renders multiple ListItems. My goal is to keep track of which ListItem is currently selected, display it in a different colo ...

Can Angular Flex support multiple sticky columns at once?

I am trying to make the information columns in my angular material table stay sticky on the left side. I have attempted to use the "sticky" tag on each column, but it did not work as expected. <table mat-table [dataSource]="dataSource" matSort class= ...

Obtain an array containing only unique values from a combination of arrays

Is there a simple way or plugin that can help me combine values from multiple arrays into one new array without duplicates? var x = { "12": [3, 4], "13": [3], "14": [1, 4] }; The resulting array should only contain unique values: [1, 3, 4]; ...

JavaScript error: Resource could not be loaded

When I have a js function called by an onclick event in a radio button, it doesn't work if the function is placed in the same ascx file where the radio button is defined. To resolve this issue, I moved the function to the ascx that includes the ascx w ...

What could have occurred if you reassigned setInterval to a variable within the useEffect hook?

Can multiple setInterval functions be defined repeatedly to the same variable in a React hook useEffect? After checking, I found that the variable has a new setInterval id value every time it is defined. However, I am curious if there are any instances re ...

All submenus will be shown simultaneously

All sub menus are displayed at once when any button that triggers the event is clicked. For a live demonstration, click here: https://jsfiddle.net/saidmontiel/734szqLg/9/ I'm interested in having only one submenu appear at a time. I am aware that ...

Angular is throwing an error when trying to create a new service: "Workspace must be loaded before it can be used."

Having trouble adding pusher.js to my angular.json file. After trying to create a new service, I encountered the following error: Error: Workspace needs to be loaded before it is used. Any tips on how to resolve this? I attempted to update the angular cl ...

Encountering a crash with the NativeDroid HTML5 JS css jQueryMobile template on iOS7

Recently, I began working on a mobile solution using the NativeDroid template, an HTML5 JS CSS template available at . However, a friend informed me that the template does not work on iOS7 devices. I tested it on multiple devices. Even when running the de ...

Submitting Data Forms with AJAX on dynamically loaded webpages

Issue with Form Submission in Ajax-Generated Page I am experiencing an issue with form submission on a page generated within AJAX. The page contains two forms, #form1 and #form2. The jQuery code for submitting the form is as shown below: jQuery("#form1" ...

Tips for aligning an image in the middle of a column within an ExtJS GridPanel

My goal is to center the icon horizontally within the "Data" column: Currently, I have applied textAlign: center to the column: Additionally, I am using CSS in the icon renderer function to horizontally center it: Despite these efforts, the icon remains ...

Steps to resolve the problem with dynamically generated text fields in Angular

For my current project, I'm implementing Angular and working with a JSON object that looks like this: items={"departure":"New York","arrival":"California","stations":[{"station":"toto"},{"station":"titi"},{"station":"tata"}]} I attempted to display ...

What could be causing issues with my application when using server-side rendered styled-components with Next.js?

I am in need of assistance with an error I've encountered. Every time I try to access the homepage of my Next.js app, it breaks and displays a cannot read data map of undefined error. The browser consistently directs me to the _document.js file, but I ...

Retrieving data from a collection with the find() method in a custom date format

Schema for Customer Data Customers.js import mongoose from 'mongoose'; const Customers = mongoose.Schema({ CustomerID: { type: String, default: "" }, Name: { type: String, default: "" }, Email: { type: String, default: "" }, Pho ...

Leveraging $http or $timeout in conjunction with $stateProvider in AngularJS

I am seeking guidance on loading a template for a specific state in Angular using $http after coming across this question on Stack Overflow: Is it possible to load a template via AJAX request for UI-Router in Angular? The documentation for ui.router demon ...

A guide to accessing real-time data in Vue.js

This is my debut project in Vue, and I am currently retrieving cart data from the server. My goal is to be able to modify the quantity using Vue. Right now, when I click on the up or down arrow to change the quantity, it gets reflected in the server databa ...

Efficiently sending data to Service Bus from an HTTP-triggered function

How can I link the output to service bus? I've configured an out binding in my Azure function: { "queueName": "testqueue", "connection": "MyServiceBusConnection", "name": "myQueueItem", "type": "serviceBus", "direction": "out" } I started ...