Angular function is executed ahead of the designated schedule

I am working with Angular components that execute two functions during initialization. The first function populates an array, and the second function takes values from that array and calls a service.

The issue I am facing is that the second function executes before the first one, causing the array to be empty and resulting in an error when the second function runs.

Here is the code snippet:

import { fromEvent, Subscription } from 'rxjs';
  ngOnInit(): void {
            this.getProducts();
            this.getLoans();
        }

getProducts() {
        this.clientService.getClientProducts(this.clientId).subscribe(
            (res) => {
                if (res.success) {
                    this.products = res.data;
                    console.log('Obtaining products');
                    console.log(this.products);
                } 
            }
        );
    }


    getLoans() {
        console.log('Obtaining loans');
        console.log(this.products);
        this.products.forEach((element) => {
            if (element.id == '4') {
                this.clientService.getClientLoan(this.clientId).subscribe(
                    (res) => {
                        if (res.success) {
                            this.loans.push(res.data);
                        } else {
                            this.hasErrorOnLoans = true;
                        }
                    },
                );
            }
        });
    }

In the console log, it is evident that the first function runs before the second one:

console log

Apologies for any language errors! Thank you.

Answer №1

The issue arises from the lack of synchronization between two asynchronous calls. One solution is to trigger the second function only after receiving data from the first one.

fetchItems() {
        this.clientService.getClientProducts(this.clientId).subscribe(
            (res) => {
                if (res.success) {
                    this.products = res.data;
                    this.fetchLoans();
                } 
            }
        );
    }

By implementing this approach, the products array will be populated before calling the fetchLoans() function.

Answer №2

Here is a helpful code snippet:

import { fromEvent, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';

 ngOnInit(): void {
        getProducts().pipe(
        map(products => products.filter(p => p.id == '4')),
        tap(filteredProducts => {
          getLoans(filteredProducts)
        })
         ).subscribe();
    }

getProducts(): Observable<ClientProduct> {
      return this.clientService.getClientProducts(this.clientId);
}


getLoans(filteredProducts) {
    filteredProducts.forEach((element) => {
      this.clientService.getClientLoan(this.clientId).subscribe((res) => {
          if (res.success) {
              this.loans.push(res.data);
          } else {
              this.hasErrorOnLoans = true;
          }
      });
  });
}

Answer №3

Searching for a resolution? Check out the following suggestions.

Potential Fix 1

async initialize() {
  await this.doSomethingFirst();
  await this.doSomethingSecond();
}

Potential Fix 2

Consider utilizing the switchMap operator or similar methods with Observables.

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

Attempting to invoke setState on a Component before it has been mounted is not valid - tsx

I've searched through various threads regarding this issue, but none of them provided a solution that worked for me. Encountering the error: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a b ...

Observe that the variable fails to update within the error handling code when utilizing httpclient

My application has an authentication service that handles user logins. The login functionality is implemented in the login() function within my login component: public login() { const val = this.form.value; if (!this.email.invalid && !t ...

Tips for validating that a TypeScript parameter is a union with a specific type

Is there a way to create a TypeScript function that confirms an argument is a union type containing another, more specific union? Here's an example scenario: type Command = { name: string [key: string]: any } type Insert = { name: 'insert ...

When trying to access instance member variables, Observable does not allow it

Within the hotelService file, I am retrieving data from the backend API that contains information about hotels. hotelService file import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders} from "@angular/common/http"; impor ...

Varied Data Transfer Objects used for requests and responses

Currently, I am dealing with MongoDB and subdocuments. MongoDB automatically adds extra fields that cannot be specified in a POST request; they can only be retrieved using a GET request. To put it simply: different data transfer objects (dtos). I am utili ...

Issue encountered with dynamic ngStyle variable: ERROR Error: Unable to locate a supporting object 'ngStyleSmall'

I have defined two variables for ngstyle ngStyleSmall = { width: '150px !important', 'max-width': '150px', }; ngStylemedium = { width: '250px !important', 'max-width&apo ...

Loop through a collection of elements of a certain kind and selectively transfer only certain items to a different collection of a different kind

When working with typescript, I am faced with the challenge of dealing with two arrays: interface IFirst{ name: string; age: number } interface ISecond { nickName: string; lastName: string; } myFirstArray: IFirst[]; mySecondArray: ISe ...

Generating sample data object for Angular app with TypeScript

I am currently constructing an angular reactive form with kendodropdownlists. My task is to establish a dummy structure of data and link this data to my angular form. Within this project, there will be an entity labeled FirmDetails, which consists of the ...

Failure of React to connect event handlers

LATEST UPDATE: After removing the output entry from my webpack configuration, the React event listeners are now functioning correctly. Currently, I am diving into the world of hand-rolling webpack configurations for a React/TypeScript application for the ...

Customize the width of the intl-tel-input field using Angular

Utilizing the Nebular ngx-admin template in my Angular application, along with ng2-tel-input for mobile number input. Below is the HTML code I am using: <div class="form-control-group"> <label class="label" for=" ...

Unexpected error arises in Typescript despite code functioning properly

As part of a practice project where I'm focusing on using webpack, ES6, npm and Typescript implementation, I have successfully set up loaders for 'awesome-typescript-loader' and 'babel-loader', which are bundling the code properly. ...

Pass a personalized header during preflight request OPTIONS in angular version 5

I have recently developed an Angular 5 app that communicates with a REST API built using Golang and hosted on an AWS EC2 instance running on port 8080. When my angular front-end code sends a POST request, the browser initiates a CORS preflight request, but ...

Retrieve content from my Tumblr API posts

Looking to retrieve my tumblr posts through an api. Successfully set up the api key using Angular2 and typescript. Utilizing jsonp to avoid any cross origin problems. Here is my current code snippet: var config = { params: { action: "query" ...

Typescript - Defining string value interfaces

I have a property that can only be assigned one of four specific strings. Currently, I am using a simple | to define these options. However, I want to reuse these types in other parts of my code. How can I create an interface that includes just these 4 va ...

Could a variable (not an element) be defined and controlled within an Angular 2 template?

For instance, envision a scenario where I have a series of input fields and I wish to assign the 'tab' attribute to them sequentially as we move down the page. Rather than hard-coding the tab numbers, I prefer to utilize a method that automatical ...

What is the process for exporting the reducer function and integrating it into the storeModule.forRoot within an Angular application?

Recently, I started delving into ngrx and decided to educate myself by going through the official documentation on their website ngrx.io. During this exploration, I came across a puzzling piece of code in one of their reducers. The file in question is cou ...

How can I set ion-option to be selected by tapping instead of having to click OK?

Currently, I am developing a mobile application and have encountered a scenario in which I utilized ion-option with ion-select, resulting in successful functionality. However, I am now aiming to remove the OK/CANCEL button so that users do not need to clic ...

How can I integrate React-Router Link as a component within Material-UI using Typescript?

Hey everyone, I've encountered an issue while trying to utilize Material UI's component prop to replace the base HTML element of a component. Error: The error message reads: Type 'Props' is not generic. This problem arises from the fo ...

Is it possible to customize the pagination-control labels from numbers (1 2 3) to different values, such as 'Anything1 Anything2 ...', by utilizing ngFor* with an array in ngx-pagination?

Is there a way to customize ngx-pagination's pagination control? Currently, the page numbers are displayed as '1 2 3' but I would like to replace them with specific string values from an array. <pagination-controls (pageChange)=& ...

Testing Angular components with Karma Server: An uncaught promise rejection occurred stating, "The code should be executed within the fakeAsync zone."

For my unit test development, I am utilizing karma. In some of my test cases, I have used fakeSync - tick() and promises. Although my tests are running successfully, there seems to be an issue with the karma server: my test.spec.ts : import { async, Co ...