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

Ways to avoid Next.js from creating a singleton class/object multiple times

I developed a unique analytics tool that looks like this: class Analytics { data: Record<string, IData>; constructor() { this.data = {}; } setPaths(identifier: string) { if (!this.data[identifier]) this.da ...

What is the solution for the error stating "Unable to locate a declaration file for the module 'request-context'."?

I am currently working on three different files: index.js, index.main.js, and app.js. My goal is to use request-context to extract a variable from index.main.js and pass it to index.js. Within my app.js file, located in the server folder, I have the follo ...

How can you adjust the size of focused elements like autocomplete or datepicker in Angular Material 15?

I recently updated to Material 15 and I'm wondering how I can adjust the height or overall size of focused components like autocomplete or datepicker. The page mentioned that density cannot be used on such components, so what other methods are availa ...

Establish a connection between a React variable and state management

In my codebase, I have an external module file named Task.ts. It contains the following: const taskList: Task[] = []; Class Task { ... } export { Task, taskList } The taskList is a list of Task objects that can be modified by the Task class. Now, i ...

Does Typescript fail to recognize the "delete" operator?

Whenever I utilize the delete operator in Typescript, it appears that the system does not recognize that the property has been eliminated. For instance: interface HasName { name: string; } interface HasNoName { name: never; } function removeName( ...

Tips for verifying the response and status code in Angular 8 while uploading a file to an S3 Presigned URL and receiving a statusCode of 200

Looking to Upload a File: // Using the pre-signed URL to upload the file const httpOptions = { headers: new HttpHeaders({ 'Content-Disposition': 'attachment;filename=' + file.name + '', observe: 'response' }) }; ...

Combine the information from 3 separate subscriptions into a single object using RxJS in Angular 9

I am seeking assistance with merging data from 3 different sensors into one object. I am using Cordova plugins to retrieve accelerometer, gyroscope, and magnetometer data. However, I am facing an issue in subscribing to all three observables simultaneously ...

Unable to locate the type definition file for 'zen-observable'

While working with Ionic 3, I decided to use the AWS default template and encountered an error: > ionic start app0 aws // aws is a default starting app in Ionic3 > cd app0 > ionic serve However, when I tried to serve the application, I received ...

What steps should I take to fix the SyntaxError occurring with the unexpected token 'export' in a React Next.js project?

Currently working on a React Next.js project and I've come across an unexpected SyntaxError: Unexpected token 'export' issue. I've reviewed the solutions provided here, but I'm having trouble grasping how to correctly implement th ...

ParcelJS takes a unique approach by not bundling imported JavaScript libraries

My NodeJS app, which is a Cloudflare Worker, seems to be having trouble with bundling the 'ping-monitor' dependency. In my main typescript file (index.ts), I import the handler module and the first line reads: const Monitor = import('ping-m ...

Making a quick stop in Istanbul and NYC to collect a few important files

Setting up Istanbul/Nyc/Mocha for test coverage in my project has been a bit of a challenge. While I was successful in running Nyc, I noticed that not all the .ts files in my project were being picked up for test coverage. When I execute npm run coverag ...

Troubleshooting Standalone Component Routing Issues in Angular 16

For my Angular 16 project code, visit this link To create the Angular 16 project with routing enabled, I used the following command: ng new myapp --standalone Then, I added other components using: ng g c components/home The boilerplate files are differe ...

What is the best way to delegate the anonymous function logic contained within the subscribe() method?

Imagine you have a code block similar to this: constructor(private _http: HttpClient) { this.fetchUsers(5); } employees: any[] = []; fetchUsers(count: number) { this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe( ...

Is it possible to apply a formatting filter or pipe dynamically within an *ngFor loop in Angular (versions 2 and 4

Here is the data Object within my component sampleData=[ { "value": "sample value with no formatter", "formatter": null, }, { "value": "1234.5678", "formatter": "number:'3.5-5'", }, { "value": "1.3495", "formatt ...

Execute --runTestsByPath on two or more distinct paths

Currently, I am utilizing the jest cli for running my tests. Jest offers a useful cli option known as --runTestsByPath, which allows me to specify the locations of my tests. Despite having unit tests spread out in various directories within my repository, ...

Running "npm start" does not automatically recompile or display code changes

My experience with my Angular project has been smooth until today. Surprisingly, without making any changes, the "npm start" command suddenly stopped working properly. The project compiles successfully, but any subsequent code changes do not trigger an aut ...

Despite my efforts to properly run, my angular component is still not being added to the angular module

After attempting to execute ng generate component elements/ElementsHome, I encountered a successful run; however, the terminal did not display the Updated file path as a hyperlink. Instead, it indicated that the component was not created within the module. ...

Does adding .catch resolve a promise?

Being new to typescript / javascript, I have limited knowledge about promises. My current scenario involves creating three distinct promises within a cloud-function and subsequently returning them using Promise.all([promise1, promise2, promise3]). Each of ...

Using Typescript with d3 Library in Power BI

Creating d3.axis() or any other d3 object in typescript for a Power BI custom visual and ensuring it displays on the screen - how can this be achieved? ...

ng-bootstrap Datepicker with current date displayed as a placeholder

I have been using ng-bootstrap Datepicker and have implemented it like demonstrated in this example on Plunker. <div class="input-group"> <input class="form-control" placeholder="yyyy-mm-dd" name="dp" [(ngModel)]="model" ngbDatepicker ...