Retrieving user id by ignoring undefined user

Viewed 44

I am logged in as a particular user and I am trying to retrieve the user id of the current user and then with it I want to make a call to a REST API to retrieve how many points this user has, the code is:

getPoints(): Observable<number> {
  return this.userAccount.get().pipe(
    switchMap(userOrUndefined => {
      console.log("User retrieved:" + userOrUndefined?.customerId)
      return this.pointsRetrievalService.getPoints(userOrUndefined);
    }),
    catchError(error => of(error)
  ))
}

where "userAccount" type is protected userAccount: UserAccountFacade here is the class

import { Observable } from 'rxjs';
import { User } from '../model/user.model';
import * as i0 from "@angular/core";

export declare abstract class UserAccountFacade {
  abstract get(): Observable<User | undefined>;
  static ɵfac: i0.ɵɵFactoryDeclaration<UserAccountFacade, never>;
  static ɵprov: i0.ɵɵInjectableDeclaration<UserAccountFacade>;
}

The issue I face is that "userAccount.get().subscribe(..)" returns firstly "undefined" an calls the service to retrieve the points and then it returns the real user and calls the service to retrieve points

Retrieving user:undefined
pointsRetrievalService called
Retreiving user:eb6cb3de-4107-4ef9-9d95-e0fb83e5c200
pointsRetrievalService called

How can I make it ignore the "undefined" user and call the get points service only with the first non "undefined" returned from this.userAccount.get()?

1 Answers

You can use filter operator, to only receive defined value. But be careful your stream will wait (and be blocked) if no correct User is emitted.

getPoints(): Observable<number> {

  return this.userAccount.get().pipe(
    filter(userOrUndefined => !!userOrUndefined),
    switchMap(user => {
      console.log("User retrieved:" + user.customerId)
      return this.pointsRetrievalService.getPoints(user);
    }), 
    catchError(error => of(error))
  )
}

It's possible to improve !!userOrUndefined syntax with :

typeof userOrUndefined !== 'undefined' && userOrUndefined !== null

UPDATE

As mentioned @Sergey, we can even simplify filtering operator as below:

filter(userOrUndefined => !!userOrUndefined) could be replaced by filter(Boolean).

More explanation about Boolean object

Related