Angular 13's APP_INITIALIZER doesn't wait as expected

Recently, I have been in the process of upgrading from okta/okta-angular version 3.x to 5.x and encountered an unexpected bug.

Upon startup of the application, we utilized APP_INITIALIZER to trigger

appInitializerFactory(configService: ConfigService)
, which involves making an HTTP call to fetch configuration data.

The function responsible for this call is as follows:

public async loadConfig(): Promise<any> {
    return this.httpClient.get('assets/config.json').pipe(settings => settings)
      .toPromise()
      .then(settings => {
        this.config = settings as IAppConfig;
      })
      .catch(exception => {
        console.log("Exception encountered while retreiving configuration");
      });
  }

Prior to migrating to okta 5.x, the APP_INITIALIZER would wait for the promise to resolve. However, after the update, it seems like other providers are now being resolved before the promise in APP_INITILIZER is completed.

This issue manifests downstream at the oktaInitializerFactory, where the following code is executed:

public oktaConfig() {
    return Object.assign({
      onAuthRequired: (oktaAuth: OktaAuth, injector: Injector) => {
        const router = injector.get(Router);
        router.navigate(['/login']);
      }
    }, this.config.oktaConfig);
  }

The problem arises because this.config.oktaConfig returns as undefined due to the APP_INITIALIZER not finishing its await operation.

Below is the full app.module.ts file for reference:

(insert updated code snippet here...)

Have you encountered any reasons why my APP_INITIALIZER might not be completing before other code runs? Oddly enough, reverting back to okta 3.x resolves this issue.

Answer №1

When upgrading from Okta 3 to 4+ or 5+, it was discovered that a change is introduced which prevents loading auth server configuration in APP_INITIALIZER as a feasible option.

To elaborate, the okta-angular plugin will try to establish a connection to the auth server before the APP_INITIALIZER completes. To address this issue, the workaround involves loading the configuration data into the injector in main.ts, triggering before the APP_INITIALIZER. Despite being contrary to the guidelines on angular.io, confirmation of this behavior has been provided by Okta support [Source]

Another user implemented a similar approach for Auth0 and faced the same dilemma, as discussed here: stackoverflow.com/a/66957293/3202440

Answer №2

I am unsure of how things were intended to function in previous iterations. There is a chain of dependencies involving appInitializerFactory, ConfigService, HttpClient, HTTP_INTERCEPTORS (specifically HttpOktaInterceptorService), and OktaAuth that seems to be causing issues.

It appears that the construction of HttpClient (which is necessary for the initializer) relies on OKTA_CONFIG being already constructed, leading to a timing issue with the order of initialization.

This dependency structure may have been introduced during a refactor rather than solely due to an update.

If I were in your position, I would consider removing the dependency on HttpClient in ConfigService and instead make the request using a native API.

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

Encountered a problem during the installation of Angular 4

Recently delving into angular, my journey began with the installation of node js on my machine. Following this link, I attempted to install angular, only to be met with the following error: gyp verb check python, inspecting if Python executable "python" i ...

Creating a Pop-Up on Website Load with HTML, CSS, and Jquery

<script> // utilizing only jquery $(document).ready(function(){ $('#overlay-back').fadeIn(500,function(){ $('#popup').show(); }); $(".close-image").on('click', function() { $('#po ...

I'm receiving /generate_seeker/?complete_list=true, but what I actually need is /generate_seeker?complete_list=true

Check out this code snippet that utilizes axios in a React project. axios.get(`https://resolab-backend.herokuapp.com/core/create_seeker`,{ params:{ complete_list : true }, headers:{ 'Authorization': `Token ${cookies.get("token")}` } ...

Javascript menu toggle malfunctioning with sub-menus

I am in the process of creating a responsive menu for a complex website. The horizontal menu transitions into a vertical layout on smaller screens, with javascript used to toggle the sub-menu items open and closed when clicked. One issue I am facing is wit ...

Uploading images using multipart in react is causing an error and cannot be completed

Trying to upload images in the database using multipart is causing an error from the API saying 'Files can't be uploaded". Checking the API in postman shows it is working fine there. There seems to be an issue with my code, but I can't ...

What is the best way to dynamically write a knockout data binding event using jQuery?

let $button = $('<input/>').attr({ type: 'button', value: data.styleData, id: buttonId, data - bind: event: { click: $parent.submitPopUp } }); An error is being displayed. ...

The NodeJS namespace appears to be missing

I'm currently utilizing Ionic2 in conjunction with socket.io Upon running ionic serve, I encounter the following error message in the terminal: TypeScript error: typings/globals/socket.io/index.d.ts(357,30): Error TS2503: Cannot find namespace &apos ...

Displaying hidden Divs in React Typescript that are currently not visible

I have an array with various titles ranging from Title1 to Title8. When these titles are not empty, I am able to display their corresponding information successfully. Now, my goal is to include a button that will allow me to show all fields. For example, ...

Interacting with JSON API data in real-time using AJAX and the power of JQuery

I'm currently working on displaying data dynamically from an API, and everything is functioning well except for the "Next" and "Previous" links. I can't seem to get them to update the value count in the search bar. My problem lies in executing my ...

The File is not being successfully sent to the controller in MVC due to AJAX returning an undefined value

I recently created an AJAXUpload method within a cshtml file in my C# MVC project: function AjaxUpload(url, method, data, successFunction, errorFunction, skipErrorDlg) { $.ajax({ contentType: false, processData: false, url: url ...

Unexpected results observed in enumerators within typescript

Could someone clarify the results that I am seeing from the code below? enum days { sun = 1, mon = 0, tues }; console.log(days[1]); // outputs tues // should output -- mon console.log(days[0]); // outputs mon // should output -- sun Furthermore, how ...

What is the recommended default value for a file in useState when working with React and TypeScript?

Can anyone help me with initializing a file using useState in React Typescript? const [images, setImages] = useState<File>(); const [formData, setFormData] = useState({ image: File }); I'm facing an issue where the file is sho ...

"Encountering difficulties while setting up an Angular project

I am currently working on setting up an Angular project from scratch. Here are the steps I have taken so far: First, I installed Node.js Then, I proceeded to install Angular CLI using the command: npm install -g @angular/cli@latest The versions of the ...

Unable to set items as sticky within mat-tabs

Is there a way to make my image stick in place using the following CSS code? position: -webkit-sticky; position: sticky; top: 1px; I have tried implementing it but haven't been successful. HTML: <mat-tab-group class="user-tabs" (selectedTa ...

TSLint Alert: Excessive white space detected before 'from' keyword (import-spacing)

I'm currently using WebStorm and working to maintain a specific code style: https://i.sstatic.net/r1n7n.png However, I encounter an issue where TSLint highlights my spacing and provides the following hint: "Too many spaces before 'from' ...

Troubleshooting date format errors when parsing two parameters in a jQuery AJAX request

Does anyone have advice on how to make an ajax call with two parameters - number and date? I encountered the following error: Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in... Here is the HTML code involved: <di ...

Issue with uploading media on Wordpress: "Unfortunately, an error occurred during the upload process. Please attempt again at a later time."

Often times, when trying to upload media from the front-end, I encounter this issue: An error occurred during the upload process It seems like the error occurs sporadically, making it even more challenging to troubleshoot. Sometimes, when logging in fo ...

Using JavaScript to ensure that a div is not hidden on page load if a checkbox is unchecked

Upon inspecting a page, I am implementing a script to check if a checkbox is selected. If not selected, the goal is to hide a specific div element. While troubleshooting this issue, I suspect the problem may be due to the lack of an inline element within t ...

Customize YouTube iframe styles in Angular 4+ with TypeScript

Has anyone been successful in overriding the style of an embedded YouTube iframe using Angular 4+ with TypeScript? I've attempted to override a CSS class of the embed iframe, but have not had any luck. Here is the URL to YouTube's stylesheet: ...

Understanding the implementation of setters in JavaScript: How are they utilized in Angular controllers?

After learning about getters and setters, I came across an example that clarified things for me: var person = { firstName: 'Jimmy', lastName: 'Smith' }; Object.defineProperty(person, 'fullName', { get: function() ...