Is it possible to initialize multiple Observables/Promises synchronously in ngOnInit()?

I am relatively new to Angular/Typescript and facing a challenge. In my ngOnInit(), I am trying to fetch settings from my backend using a GET request. After that, I need to subscribe to an observable. The observable updates the widgets' content over time while the settings determine the number and type of widgets to display.

Essentially, I want the ngOnInit() to wait for the response from getGeneralSettingsOnce before starting other subscriptions.

This is my request function:

getGeneralSettingsOnce(): Promise<any> {
    return this.http.get(`${environment.API_URL}/get_general_settings`).toPromise()
    .then(response => {
      return response
    })
  }

Initially, I tried making the ngOnInit of my main page an async function and awaiting the promise. However, this resulted in the error

Cannot read properties of undefined (reading '-1')
for some static widgets on my main page. As per an article I read, this might be because the main page is not fully loaded when the browser tries to render it. Source: article

Segments of the ngOnInit of my main page

async ngOnInit() {  
    let generalSettings = await this.localService.getGeneralSettingsOnce(); //calling the promise
    this.widgetCount = generalSettings.widget_count

    // other subscriptions
    this.localService.getWidgetContent().subscribe(
      data => { this.loadWidgetContent(data)
      } 
    }
}

My question is how can I achieve my goal of initializing the settings first and then subscribing to other request functions as if it were synchronous, preferably without errors.

Answer №1

If you're looking to retrieve data from observables, consider using a combination of the subscribe method (a common way to get data from observables) along with the switchMap operator, which allows for sequential execution of one observable after another!

    subscription: Subscription = new Subscription(); // <- keeps track of observables for easy unsubscription

    ngOnInit() {
        this.subscription.add( // <- centralizes all subscriptions in one place
            this.localService
                .getGeneralSettingsOnce()
                .pipe(
                    switchMap(generalSettings => {
                        this.widgetCount = generalSettings.widget_count;
                        // other subscriptions
                        return this.localService.getWidgetContent();
                    })
                )
                .subscribe(data => {
                    this.loadWidgetContent(data);
                })
        );
    }

    ngOnDestroy() {
        this.subscription.unsubscribe(); // <- ensures all subscribers are properly unsubscribed to avoid memory leaks
    }

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

Stop certain sections of Typescript code from being compiled

In my scenario, I have two classes: class A and class B. Class B extends class A. The issue arises when we consider a method in both classes. Class A has a method that accepts AProperties enum as its first argument. However, class B has a similar method th ...

Encountered an issue with Angular Material sidenav: The synthetic listener @transform.start was found

Click here to visit the StackBlitz link Encountering an issue while attempting to utilize the material side nav. Error message: preview-29b0f46fcc27b310236ab.js:1 ERROR Error: Uncaught (in promise): Error: Found the synthetic listener @transform.start. P ...

Tips for importing font files from the node_module directory (specifically otf files)

We cannot seem to retrieve the fonts file from the node module and are encountering this error message. Can't find 'assets/fonts/roman.woff2' in 'C:\Projects\GIT2\newbusinessapp\projects\newbusinessapp\src ...

What does the 'key' parameter represent in the s3.put_object() function?

Currently, I'm utilizing Boto in my project to upload artifacts to an s3 bucket. However, I am uncertain about the usage of the Key parameter within the put_object() method: client.put_object( Body=open(artefact, 'rb'), Bucket=buc ...

Tips for fixing TypeScript compiler error TS2339: Issue with accessing 'errorValue' property in Angular 5 project

Within a component, I have developed a function to manage errors returned from a Rest Service and determine the corresponding error message to display to the user. This method accepts an error object (custom data structure from the service), navigates to e ...

Leveraging Global Variables for Validation in Angular (Angular 10)

I am currently creating a form in Angular 10 which involves the use of validators. Specifically, I have been utilizing the Validators.min() method within my form... Instead of manually inputting the value '100' in the Validators.min('100&ap ...

What steps can be taken to ensure that the requestAnimationFrame function does not redraw the canvas multiple times after a button click?

I am currently working on a project where I am drawing a sin wave on a canvas and adding movement to it. export class CanvasComponent implements OnInit { @ViewChild('canvas', { static: true }) canvas: ElementRef<HTMLCanvasElement>; ...

Instructions on changing the color of a full row in the table when the value is missing within the <td> tag. The value is retrieved from an API and iterated through

In this scenario, if the value inside the <tr> tag is null for a cell, then the entire row should be displayed in a different color. The code I have written for this functionality is: <ng-container *ngFor="let row of table?.rows; let rowIndex ...

What is the comparable alternative to promise<void> in observables?

I've been working with Angular using TypeScript and I'm attempting to return a promise from an observable. What is the correct way to accomplish this? So far, I have tried the following: of(EMPTY).toPromise() // error: Promise<Observable<n ...

Using subscribe method to return an observable within a function

Looking to develop a service that interacts with the Spotify API, I require an authorization bearer token. The token is obtained from another service, which returns an observable. How can these two components be integrated together? Initial attempt: getS ...

Having an issue with displaying the country name and country code in a table using the Angular7 custom pipe

country code: "ab", "aa", "fr", ... I need to create a custom pipe that will convert a countryCode into a countryName, such as: "ab" → "Abkhazian", "ch" → "Chinese", "fr" ...

React-snap causing trouble with Firebase

I'm having trouble loading items from firebase on my homepage and I keep running into an error. Does anyone have any advice on how to fix this? I've been following the instructions on https://github.com/stereobooster/react-snap and here is how ...

What is the correct method for integrating jQuery libraries into an Angular project version 10 or higher?

Currently, I am facing difficulties while attempting to install the jquery and jquery-slimscroll packages into an Angular project (version greater than 10). It appears that the installation of these packages has not been successful. In light of this issue, ...

Using local fonts with Styled Components and React TypeScript: A beginner's guide

Currently, I'm in the process of building a component library utilizing Reactjs, TypeScript, and Styled-components. I've come across the suggestion to use createGlobalStyle as mentioned in the documentation. However, since I am only working on a ...

Troubleshooting issues with accessing the _id property using Typescript in an Angular application

Encountering an Angular error that states: src/app/components/employee/employee.component.html:67:92 - error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is ...

How can we ensure a generic async function with a return type that is also generic in Typescript?

I'm currently working on a function that retries an async function multiple times before rejecting. I want to make sure the typescript typings of the retry function are maintained and also ensure that the passed function is of type PromiseLike. Creat ...

Disabling the use of console.log() in a live environment

In an effort to disable console logs for production environments in my angular application, I implemented the code below. While it successfully suppresses logs in Chrome, IE 11 continues to display them. Here is the snippet from main.ts: if (environment. ...

Personalize the bootstrap classes within Angular app development

I'm currently utilizing bootstrap 4 and sass within my angular 6 application development. My goal is to create a customized nav tab in my application by slightly modifying the bootstrap nav-tabs and nav-link classes. However, the changes I make to th ...

Nest.js: initializing properties from a superclass in a controller

I have a question about unit testing controllers in the Nest.js framework. My issue is that the property from a superclass is not initialized in the controller class when creating a test module. Here is an example of the code I am referring to: export cl ...

I'm having trouble establishing a connection with the Appwrite platform

Encountered an issue while trying to connect to appwrite. The specific error message is: Uncaught (in promise) TypeError: Failed to construct 'URL': Invalid URL at Account.<anonymous> (appwrite.js?v=d683b3eb:932:19) at Generator.nex ...