-2

As i mentionned above, i use a function that sends an http request to the backend to get some data, which returns an observable; when i call that function, i have to subscribe to it so i can handle its return, then i do some additional code after the subscription, including some if statements, what i noticed is that the code below the subscribe method gets executed before getting the data. i tried working with async an await , but it doesn't seem to work until i convert the return (observable) to a promise, using toPromise(); then it works fine; my question, is there any way to make the code below subscribe until subscribe() finishes, witout using toPromise() (since it is deprecated);

 public login(
    usernameOrEmail: string,
    password: string
  ): Observable<AppUser> {
    /*
      -tried getting data directly from the backend instead of fetching everything onInit(which i think is not a good idea)
      but that dosn't seem to work since return of http request is an observable, and takes a bit more of time,
      and since i need to do more tests on the data returned (as you see below), the code keeps executing 
      without having the data yet.
     
    */
  this.userService.getUserByUsername(usernameOrEmail).subscribe({
      next: (response: AppUser) => {
        this.authenticatedUser = response;
      },
      error: (error: Error) => {
        throwError(() =>error);
      }
    });

    if (this.authenticatedUser == undefined) {
      return throwError(() => new Error('User not found'));
    }
    if (this.authenticatedUser.password != password) {
      return throwError(() => new Error('Bad credentials'));
    }
    return of(this.authenticatedUser);
  }

 

Thanks in advance.

mouse
  • 15
  • 2
  • The code should be in the subscribe handler - it's an async process – Drenai Sep 06 '22 at 21:27
  • thank you @Drenai for answering, if i get your answer, i should add the code below the subscribe method inside of subscribe itself; but if you can see at the end my method returns an observable of AppUser, but my authenticatedUser will be undefined then , because the instruction( return of(authenticatedUser)) wont wait for subscribe to finish executing – mouse Sep 06 '22 at 21:34
  • 1
    Does this answer your question? [How do I return the response from an Observable/http/async call in angular?](https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular) – R. Richards Sep 06 '22 at 21:38
  • thank you so much for answering @R. Richards , i understand that i should put my code inside of subscribe(), but the problem is that my function returns an observable(the last instruction), which i can't put inside subscribe, in this case the return will be undefined – mouse Sep 06 '22 at 21:57
  • return this.userService.getUserByUsername(usernameOrEmail), And use operators do your logic – Eddy Lin Sep 07 '22 at 00:41

1 Answers1

-1

For those that may have the same issue, I solved it by using toPromise() for the first time, but since it's deprecated I was looking for a better option, hence I found firstValueFrom and lastValueFrom, and since my method should return a single value that was appropriate for me, then my code becomes:

  public async login(
    usernameOrEmail: string,
    password: string
  ): Promise<Observable<AppUser>> {
    try {
      let response = await this.userService.getUserByUsername(usernameOrEmail);
      this.authenticatedUser = await firstValueFrom(response);
    } catch (error) {
      this.errorMessage = error;
    }
    if (this.authenticatedUser == undefined) {
      return throwError(() => new Error('User not found'));
    }
    if (this.authenticatedUser.password != password) {
      return throwError(() => new Error('Bad credentials'));
    }
    return Promise.resolve(of(this.authenticatedUser));
  }

now my code runs perfectly. Thank you so much for those who answered.

lepsch
  • 8,927
  • 5
  • 24
  • 44
mouse
  • 15
  • 2