Angular 10 does not fulfill promises as expected

In the Angular 10 project I'm working on, I encountered an issue while trying to call an API request asynchronously using promises. The code I wrote didn't seem to execute the API call as expected and kept exiting at the first line without progressing further. I have been unable to determine the cause of this problem, as it neither resolves nor rejects.

Here is a snippet of my TypeScript code:

public setUser(): () => Promise<any> {
return (): Promise<any> => {
  return new Promise((resolve, reject) => {
    // Retrieve user details
    this.api.get<any>(environment.apiUserRoot + `/Users/current`).subscribe(
      userData => {
        this.storage.clearIdentity();
        this.assignLoginUserToUser(userData.body);
      },
      err => {
        this.storage.clearIdentity();
      }
    );
  });
};
}

private assignLoginUserToUser(user: UserModel): void {
    this.loginUser = user;
}
 

public getUserContext(): UserModel {
   this.setUser();
   return this.loginUser;
}

Answer №1

It seems a bit complicated, so I suggest simplifying it like this:

public setUser(): void {
  this.api.get<any>(environment.apiUserRoot + `/Users/current`).subscribe({
    next: (userData) => {
      this.storage.clearIdentity();
      this.assignLoginUserToUser(userData.body);
    },
    error: (err) => {
      this.storage.clearIdentity();
    },
  });
}

If you need a return value, there are different options based on the rxjs version you are using:

public setUser(): Promise<any> {
  return this.api.get<any>(environment.apiUserRoot + `/Users/current`)
  .toPromise().then(userData => {
    this.storage.clearIdentity();
    this.assignLoginUserToUser(userData.body);
    return userData;
  }).catch(() => {
    this.storage.clearIdentity();
  });
}
  • If you have firstValueFrom, you can do it like this:
public setUser(): Promise<any> {
  return firstValueFrom(this.api.get<any>(environment.apiUserRoot + `/Users/current`))
  .then(userData => {
    this.storage.clearIdentity();
    this.assignLoginUserToUser(userData.body);
    return userData;
  }).catch(() => {
    this.storage.clearIdentity();
  });
}

For obtaining the user, you have several options depending on your async implementation choice (observable or promise; observables are recommended):

  • With observables, the setUser method should not subscribe itself but handle side effects with tap and return the observable for later use.
public setUser(): Observable<UserModel> {
  return this.api.get<any>(environment.apiUserRoot + `/Users/current`).pipe(
    tap(result => {
      this.storage.clearIdentity();
      this.assignLoginUserToUser(result.body);
      return result.body;
    }),
    catchError(err => {
      this.storage.clearIdentity();
      return of(null);
    })
  );
}

The getUserContext method should now return an Observable instead of being synchronous:

public getUserContext(): Observable<UserModel> {
   return this.setUser();
}

This means that the calling code needs to subscribe to the observable returned by getUserContext like this:

getUserContext().subscribe(user => {
  // process user data here.
});
  • With promises, you should return the promise obtained from the setUser method using one of the implementations mentioned above (with .toPromise or firstValueFrom)
public getUserContext(): Promise<UserModel> {
   return this.setUser().then(result => result.body);
}

The calling code also needs adjustments to handle the fact that getUserContext is no longer synchronous:

const user = await getUserContext();

or use then

getUserContext().then(user => {
  // process user data here.
});

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

Add flexible templates into List element in Ionic version 3

My Progress Being a newcomer to ionic, I successfully created a List component in ionic 3 that retrieves JSON data from the server and displays it as a list layout on specified pages using a list selector. Objective I am looking to showcase various list ...

Highcharts - resolving cross-browser e.Offset discrepancies in mouse event detection on charts

I need to determine if the mouseup event is inside the chart and display the coordinates of the point. The code works in Chrome but not in Firefox due to the lack of the event.offset property. jQuery(chart.container).mouseup(function (event) { eoff ...

Invoke a Node.js script from a Spring Boot application to pass a Java object to the script. The script will modify the object and then return it back to the originating class

class Services { Address address = new Address(....); /* Invoke NodeJs script and pass address object In the js script modify address object var address = getAddress() Modify address object Return address obj ...

Getting the perfect typings installed from DefinitelyTyped

In my current attempt to install typings (version 1.3.2) for the malihu-custom-scrollbar-plugin, I am facing an issue with some wrong type identification error (Error TS1110: Type expected). This error is caused by the use of string literal types syntax li ...

Automatically fill in options for up to 3 dropdown menus depending on the choices made in the previous dropdown menu

I've looked through similar questions but haven't found the solution I need. Here's a sample fiddle with some example data for years, months, and days. Instead of manually adding select option divs for each year, I want the div id to dynami ...

Is there a way to determine the names of the functions that are being called?

I'm working on mastering Google Development Tools. Is there a way to determine which specific functions, especially those in Javascript, are needed before a page can load successfully? ...

Switching between custom dropdowns in Angular

I've implemented a custom dropdown selector with the functionality to toggle when clicked anywhere else on the browser. The toggleModules() function is responsible for handling the toggling within the dropdown. Data: modules=["A", "B", "C", "D", "E", ...

Encountered an issue with reading the property childnotes of null during data retrieval using ajax in PHP

Hello, I am encountering an error while trying to fetch data using ajax. The error message is "Cannot read property 'childNodes' of null". Can anyone help me identify what might be wrong with my code? I have created a form to search for data with ...

Tips for receiving a reply from S3 getObject in Node.js?

Currently, in my Node.js project, I am working on retrieving data from S3. Successfully using getSignedURL, here is the code snippet: aws.getSignedUrl('getObject', params, function(err, url){ console.log(url); }); The parameters used are: ...

What is the best method for saving HTML form data into a Node JS variable?

I am facing an issue with setting the values of HTML form inputs onto my Node JS variables. In the JavaScript code below, I am struggling to assign values to the variables "hostname" and "port," which should then be concatenated to create a new variable ca ...

Addressing the spacing and alignment issues within the progress bar

I need some help with my Angular app. I am currently working on creating a progress bar, but I am facing some issues with the alignment of the bars. Here is the code snippet that I have used: CSS: .progressbar { position: relative; height: 56px; mar ...

The specified reference token grant value of [object Object] could not be located in the store

Currently, I am working with NestJs along with the oidc passport strategy using identityserver. Below is a snippet of the code: import { UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; ...

What is the procedure for deactivating a plugin within the replace feature of CkEditor?

Is there a way to disable image-upload on specific CKEditor textareas without affecting all of them through the config.js file? I'm wondering if it's possible to achieve this using the .replace method. For example: CKEDITOR.replace("meTextarea" ...

Implementing dynamic display of div based on dropdown selection in typescript

A solution is needed to display or hide specific div elements based on a dropdown selection using Typescript. Sample HTML file: <select class="browser-default custom-select"> <option selected>single</option> <option value="1"> ...

Using jQuery to trigger a click event on a radio button prevents the button from being checked

Having trouble with using the .trigger("click"); function on radio buttons to activate a button in a form. When I use the code below, the button is triggered as expected. However, it seems to be interfering with the radio button, causing it to appear chec ...

I am having trouble with retrieving and showing Json data in a table using axios within a React component

Struggling to access JSON data using hooks to display it in the <p> tag but encountering an error - "TypeError: states.map is not a function". I attempted utilizing Array.from() to convert my JSON to an array, yet it neither displayed anything nor pr ...

Creating dynamic SQL queries for bulk inserting data into Postgres using Vercel

Can anyone help me with creating an SQL bulk insert query using the sql helper from @vercel/postgres? I have a array of objects with different property types (number, string, date) and need to dynamically build the query. Simply creating a string and passi ...

Ways to implement functional component in ReactJs

I am currently working with Reactjs and utilizing the Nextjs framework. In my project, I am attempting to retrieve data from a database using Nextjs. However, I am encountering an error that states "TypeError: Cannot read property 'id' of undefin ...

What steps can be taken to initiate Nx Release on the apps/* when modifications are made to the connected libs/* modules?

Trying out the nx release command but struggling to get it to release an app when there are changes to a dependent module. Examining the graph below, you can see that I have 3 apps, with 2 depending on the shared-ui module. If I directly modify the apps, ...

Simple Steps to Convert an HTML String Array into Dynamic HTML with AngularJS Using ng-repeat

Below is an array consisting of HTML strings as values. How can I convert these strings into executable HTML code to display them? [ {html:'<button>name</button>'}, {html:'<table > <thead> <tr> <th>#</ ...