flutterdartdartz

With dartz is it possible to pass a failure on to the function that is folding my either


I have the following code

class GetAuthUserUseCase {
  final AuthRepository _authRepository;

  GetAuthUserUseCase({
    required AuthRepository authRepository,
  }) : _authRepository = authRepository;

  Future<Either<Failure, AuthUser>> call() async {
    final userResponse = await _authRepository.getUser();

    var user = userResponse.fold(
      (Failure l) => //How can I return the failure from the call function?,
      (AuthUser r) => r,
    );

    final accessTokenExpiresAtMilliseconds =
        user.accessTokenIssuedAtMilliseconds + user.accessTokenExpiresInMilliseconds;
    final accessTokenExpiresAtDateTime =
        DateTime.fromMillisecondsSinceEpoch(accessTokenExpiresAtMilliseconds);

    if (DateTime.now().isBefore(accessTokenExpiresAtDateTime)) {
      return userResponse;
    }

    return _authRepository.refreshUser(
      user: user,
    );
  }
}

In my use case I have some business logic to determines whether I need to refresh a users access token or not. Based on that I refresh my user. But I need to load my user first with getUser() in order to determine if the access token has expired.

The getUser() will return an Either<Failure,AuthUser> so I fold that to get the user. But what I want is tho propagate the failure so it terminates the call method and outputs that failure from the call method.

I would like to avoid doing a type check for Failure or AuthUser if possible since I think it will make my program less robust.

Is this possible?


Solution

  • For this case, you can use isLeft() to check the failure. and isRight() on success.

    Future<Either<Failure, AuthUser>> call() async {
        final userResponse = await _authRepository.getUser();
    
        if(userResponse.isLeft()){
           // do your stuffs       
         }
    

    Inside this, you may like to access data directly, this extension will help

    extension EitherX<L, R> on Either<L, R> {
      R asRight() => (this as Right).value; //
      L asLeft() => (this as Left).value;
    }