Search code examples
angularsubscription

Angular - How to return a bool from a Subscription in my service-component?


I have a login.service.ts, and my login.component.ts

In my login component, I have an input field, where the user inputs a username, and when he hits "login", we check if that user name is valid with this call:

<button color="primary" mat-raised-button (click)="loadUserInfo(email.value)">
      continue
      <mat-icon>arrow_forward</mat-icon>
    </button>

loadUserInfo(userLogin: string) {
this.loginService.processLogin(userLogin);
}

which calls my service:

processLogin(loginId: string) {
return this.http.get("api/" + loginId).subscribe(
(user: User) => {

        this.userSub.next(user);
      },
      err => {
        console.error("Username not valid");
      }
    );
  }

I cannot wrap my head around the following: If the call is unsuccessful, and there is no user with that username, how can I, in my login.component.ts, show a error message under the input field? I would need a bool or something, but the error handling is in the service component, so not really sure what is the best way

I would put under my input field this:

  <div *ngIf="userNotValid"> Error, this user doesn't exist</div>

But what should be the best way to handle this scenario? The users presses the button, the API returns the error, and now, how do I show an error in the login-component html file? Thank you


Solution

  • as many suggested, I should make it an observable in my service, and subscribe to it from my component, I didn't want to do this as I would need to change other stuff as well, but if it's the cleanest way I just might do it.

    Would it make sense, doing it like this, so it both returns a boolean, and if the User is valid, it will fire next() to my behaviourSubject that stores the current user?

    processLogin(loginId: string): Observable<boolean> {
        return this.http.get("api/" + loginId).pipe(map(
          (info: UserInfo) => {
            console.log("userinfo:", info);
            return info;
          }),
          catchError(err => of(null as UserInfo))
        ).pipe(tap(
          uInfo => {
            this.userSub.next(uInfo);
          }
        ),
        map(u => u != null)
        );
      }
    

    am I doing this correctly? Or could I improve it? In my view, now I have both things I wanted, a Boolean as return, and in case of Existing user, it will next() the value.