reduxsaga / redux_saga

Redux Saga library for Dart and Flutter
MIT License
39 stars 7 forks source link

Inheritance and type pattern matching #14

Closed hacker1024 closed 4 years ago

hacker1024 commented 4 years ago

I have some abstract auth actions:

abstract class AuthStarted {
  const AuthStarted();
}

abstract class AuthStopped {
  final bool successful;

  const AuthStopped(this.successful);
}

And then I have extensions for cached and remote authentication methods:

class RemoteAuthStarted extends AuthStarted {
  const RemoteAuthStarted();
}

class RemoteAuthStopped extends AuthStopped {
  const RemoteAuthStopped(bool successful) : super(successful);
}

class StorageAuthStarted extends AuthStarted {
  const StorageAuthStarted();
}

class StorageAuthStopped extends AuthStopped {
  const StorageAuthStopped(bool successful) : super(successful);
}

Finally, I have these sagas to handle navigation:

Iterable<Effect> watchStorageAuthStopped() sync* {
  yield TakeEvery(navigateAfterAuthStopped, pattern: AuthStopped);
}

Iterable<Effect> navigateAfterAuthStopped({
  required AuthStopped action,
}) sync* {
  if (action.successful) {
    yield* _navigateTo(Route.collection);
  } else {
    if (action is StorageAuthStopped) {
      // This was an attempt to log in from storage, so no login was in storage.
      // Navigate to the login page.
      yield* _navigateTo(Route.collection);
    }
  }
}

I would expect my TakeEvery statement to run on all types of AuthStopped, but this isn't what happens. The _typeMatcher checks the runtimeType property, which doesn't take inheritence into account.

I propose we use is instead, as it seems like a better fit.

bilal-uslu commented 4 years ago

TypeMatchers check the exact type. They don't check inheritance. In order to check inheritance you can use FunctionMatcher. For instance,

yield TakeEvery(navigateAfterAuthStopped, pattern: (dynamic action) => action is AuthStopped);

or you can use a List to group actions without inheritance check;

yield TakeEvery(incrementAsync, pattern: [RemoteAuthStopped, StorageAuthStopped]);

hacker1024 commented 4 years ago

I see. Thanks for the answer, and sorry for the redundant issue!