The function is failing to return the expected value received from the observable subscription

I am attempting to verify the existence of a user in an Angular's in-memory API by validating their username. The function checkUsernameExists(username) is supposed to return an Observable<boolean> based on whether the API responds with undefined or a user object. However, I am encountering an issue where it always returns false regardless of whether the username exists or not. I have confirmed that the getUser() function works correctly as it returns undefined for non-existing users and a user object for existing ones.

If possible, I would prefer to only make adjustments to the checkUsernameExists function. This function is used for an async validator that is currently functioning properly. I have searched extensively for a solution to this problem but have been unable to find anything that is not deprecated or does not meet the requirements for it to work effectively.

  usersUrl = '/api/users';

  constructor(private http: HttpClient) {}

  users = this.http.get<User[]>(this.usersUrl).pipe(shareReplay());

  // retrieves a user object when subscribed to
  getUser(username: string): Observable<User | undefined> {
    return this.users.pipe(
      take(1),
      map((users: User[]) => {
        return users.find((user) => user.username === username);
      })
    );
  }

  // checks if user exists
  checkUsernameExists(username: string): Observable<boolean> {
    var userValid = false;

    this.getUser('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a4c0d1c9c9ddd1d7c1d6e4c0d1c9c9dd8ac0d1c9">[email protected]</a>')
      .pipe(take(1)).subscribe(
        result => {
          if (result === undefined) {
            console.log('result: ', result);
            return (userValid = false);
          } else {
            console.log('result: ', result);
            return (userValid = true);
          }
        }
      );

    console.log(userValid)  // regardless of the username, the value always remains the same as its initialization (false)

    return of(userValid);
  }

Answer №1

the issue lies in the order of operations within the checkUserNameExists method

you need to wait for the observable to complete before returning a value, but your code currently calls the observable this.getUser and then immediately returns return of(userValid).

as a result, the value of userValid remains the default false because the observable has not completed yet.

to fix this, update your method to:

checkUsernameExists(username: string): Observable<boolean> {
    return this.getUser('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ea8e9f8787939f998f98">[email protected]</a>').pipe(
      .map( (result: any) => {
        if (result === undefined) {
          console.log('result: ', result);
          return (userValid = false);
        } else {
          console.log('result: ', result);
          return (userValid = true);
        }
     })
  );

}

this modification ensures that the userValid is only returned after the observable has completed its operation.

it also eliminates the need for double subscription, streamlining the process.

Answer №2

/* Consider using a promise for this task */

validateUsername(username: string): Promise<any> {
        return new Promise<any>((resolve, reject) => {
          this.getUser('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e4a5b4343575b5d4b5c6e4a5b434357004a5b43">[email protected]</a>')
            .subscribe(
              async (result: any) => {
                if(result) 
                {            
                  console.log('result: ', result);
                    resolve(result)         
                }
                else if(result && result.IsError)  
                {
                  console.log('result: ', result);
                  reject(result.Error)  
                }
            },
            (err) => {
              reject(err)   
            });        
        });
      }

/* To Use the Method => Handle the result accordingly */

 await validateUsername("Your_Username").then((res) => {
    console.log(res)
    }, (err) => {
    console.log(err)
    })

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

Can you use getters and setters in a TypeScript declaration file?

I am facing an issue with a declaration file for the openUi framework. The framework utilizes a get<propname>() and set<propname>(var) syntax for its properties. In traditional JavaScript, the setup would look like this: sap.ui.getCore().atta ...

Unable to locate a suitable version for internal-slot@^1.0.3 at this time

I'm encountering an issue with the npm installation process. When attempting to run npm install on my Angular application, I received an error message that is shown in the image above : No matching version found for internal-slot@^1.0.3 I att ...

Having trouble integrating NEXT AUTH with Firebase due to an error: "Cannot import statement outside

Let's take a look at our firebase configuration file: import { getFirestore } from "firebase/firestore"; export const firebaseConfig = { apiKey: process.env.FIREBASE_API_KEY, authDomain: process.env.FIREBASE_AUTH_DOMAIN, projectId: pr ...

A guide on including a class to a DOM element in Angular 6 without relying on Jquery

Currently, I have created a component template using Bootstrap that looks like this: <div class="container"> <div class="row my-4"> <div class="col-md-12 d-flex justify-content-center"> <h2> ...

Error message pops up in WebStorm when attempting to access the map object in Angular

Within one of the services in my Angular application, I have utilized the map() function to retrieve data from the GitHub API. getUser(username: string) { // Regular Expression used for String Manipulation return this.http.get('https://api.github.com ...

Refreshing a page in Angular 4/5 using TypeScript

I am currently working on a single-page application that utilizes routes for navigation: this.router.navigate(['/customer-home'], { skipLocationChange: true }); While on the customer home page, I have a feature to add a new customer via a REST ...

Prohibit using any as an argument in a function if a generic type is

I have attempted to implement this particular solution to prevent the calling of a generic function with the second type being equal to any. The following code snippet works fine as long as the first generic parameter is explicitly specified: declare fu ...

What benefits does injecting FormBuilder offer over simply declaring it?

In reviewing the code, I observed that the FormBuilder constructor is set as a default empty constructor. export class FormDI { constructor(private fb: FormBuilder) {} private buildForm() { let form = this.fb.group({...}); } } export clas ...

Ways to dynamically apply styles to the component tag depending on the visibility of its content

Consider a scenario where you have a component with logic to toggle the visibility of its contents: @Component({ selector: 'hello', template: `<div *ngIf="visible"> <h1>Hello {{name}}!</h1></div>`, styles: [`h1 { fo ...

Tips on selecting data from an array to populate a mat-selection-list

When I receive a string like this from the API: 55,118,122,126,116,58,125,119,132. These are the ids that I need to work with in my Angular mat-selection-list. My goal is to initially select these values and update existing data before sending it back thro ...

What is the mechanism behind the integration of Cross Origin functionality between Spring Boot and Angular CLI?

I came across this helpful Spring/Angular tutorial that I've been following. However, when I try to run my application, I encounter the following error: The browser is blocking access to XMLHttpRequest at 'http://localhost:8080/api/employees&ap ...

Tips for avoiding a form reload on onSubmit during unit testing with jasmine

I'm currently working on a unit test to ensure that a user can't submit a form until all fields have been filled out. The test itself is functioning correctly and passes, but the problem arises when the default behavior of form submission causes ...

You can't access the values from one subscribe in Angular 2 within another subscribe (observable) block

Is there a way to properly handle the values from the subscribe method? I am facing an issue where I want to use this.internships in another subscribe method but it keeps returning undefined. Your assistance is greatly appreciated! Code: ngOnInit(): voi ...

Exploring how to utilize checkboxes in Angular Material for data filtering from a database. Encountering an issue with the error message "nameValue

When attempting to utilize checkboxes to filter data in a material table, I ensured there were no errors present on my terminal or console. However, upon checking a checkbox in the browser, an error message stating "nameValue.toLowerCase is not a function" ...

An easy guide to using validators to update the border color of form control names in Angular

I'm working on a form control and attempting to change the color when the field is invalid. I've experimented with various methods, but haven't had success so far. Here's what I've tried: <input formControlName="pe ...

Is it advisable to use an if statement or question mark in TypeScript to prevent the possibility of a null value?

Currently delving into TypeScript and exploring new concepts. I encountered a scenario where inputRef.current could potentially be null, so I opted to directly use a question mark which seems to work fine. However, in the tutorial video I watched, they use ...

Leveraging Angular's capability to import files directly from the assets

I recently installed a library via npm and made some modifications to one of the modules. python.js If I delete the node_modules folder and run npm install, I am concerned that I will lose my changes. Is there a way to preserve these modifications by mov ...

What is causing the element to disappear in this basic Angular Material Sidenav component when using css border-radius? Check out the demo to see the issue in action

I have a question regarding the Angular Material Sidenav component. I noticed that in the code below, when I increase the border-radius property to a certain value, the element seems to disappear. <mat-drawer-container class="example-container" ...

Nested Angular click events triggering within each other

In my page layout, I have set up the following configuration. https://i.stack.imgur.com/t7Mx4.png When I select the main box of a division, it becomes highlighted, and the related department and teams are updated in the tabs on the right. However, I also ...

How do I implement a dynamic input field in Angular 9 to retrieve data from a list or array?

I'm looking to extract all the strings from the Assignes array, which is a property of the Atm object, and populate dynamic input fields with each string. Users should be able to update or delete these strings individually. What approach can I take us ...