Skip to content

Add example to OnWillChange docs #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ejabu opened this issue Aug 22, 2018 · 4 comments
Closed

Add example to OnWillChange docs #75

ejabu opened this issue Aug 22, 2018 · 4 comments

Comments

@ejabu
Copy link

ejabu commented Aug 22, 2018

/// Note: Using a [BuildContext] inside this callback can cause problems if

is there any example of using this ?

I got stressed Out since my TabBar always rebuild after dispatching a filter. Since then, the TabController animation which shows the current tab index will never be shown

@DizWARE
Copy link

DizWARE commented Aug 26, 2018

OnWillChange happens before the Widget is rendered due to a change in the store (or view model if you've set it up to limit the update count). Your view model will be the latest version, but your widget tree will still be the previously rendered version. This is a perfect place to navigate to a new page if your view model is looks a certain way or you could use it to post a snack bar in response to your change.

It would look something like this:

onWillChange: (viewModel) {
    if (viewModel.wasSuccessful) {
        Scaffold.of(context).showSnackBar(SnackBar( content: Text("Action was Successful!")));
    }
}

The didChange callback is called when the widget tree is still volatile. Your buildContext by this point won't be fresh enough to do something like use Navigator. This was a lesson i learned the hard way, when I tried to integrate router functionalities into my store.

I can't tell by your question, if you are having troubles with something refreshing when it shouldn't. It kind of seemed like that was an original problem that led to your current problem. If that is the case, be sure you've set up your StoreConnectors to only refresh each widget by adding overrides to the == operator and the get hashCode for the view models you want to limit your updates with, using the distinct flag.

@brianegan brianegan changed the title How to use onWillChangeCallback ? Add example to OnWillChange docs Aug 31, 2018
@MihaMarkic
Copy link

MihaMarkic commented Jan 21, 2019

@brianegan Is there a way to compare the old and new viewmodel? Or old and new store?
For example: In @DizWARE sample, the snack bar would appear each time the widget is rebuilt. Something like

if (viewModel.wasSuccessful && !oldViewModel.wasSuccessful) {
    // show SnackBar
}

would be better I think. Or how do you handle one time property changes like this?

@stargazing-dino
Copy link

stargazing-dino commented Apr 19, 2019

In React, I used to avoid diffing states altogether by simply having my actions return a promise and then chaining a .then to them to show any alerts, but I can't find a simple example that does this with flutter_redux and flutter_redux_thunk.

Either way, I'd love to know if anyone has found a workaround for showing the snack bar just once.

EDIT:
I think I got it working as I wanted. Not sure why I thought I had to manually create a promise like I had to in JavaScript. Here's my login action and how I called a SnackBar just in case it helps anyone (I'm also using flutter_redux_navigation):

// auth_actions.dart
Future<String> loginAction(Store<AppState> store) async {
  store.dispatch(IsLoadingAction(true));

  try {
    GoogleSignInAccount _currentUser = await _googleSignIn.signIn();
    GoogleSignInAuthentication _googleAuth = await _currentUser.authentication;

    store.dispatch(LoginAction(_currentUser, _googleAuth));
    store.dispatch(NavigateToAction.pushNamedAndRemoveUntil(
      '/home',
      (Route<dynamic> route) => false,
    ));
    store.dispatch(IsLoadingAction(false));

    return '';
  } catch (error) {
    store.dispatch(AuthError(error.toString()));
    store.dispatch(IsLoadingAction(false));

    return error.toString();
  }
}
// signin.dart
/* ... */
GoogleSignInButton(
  onPressed: () async {
    String error = await vm.login();
    if (error != '') {
      Scaffold.of(context).showSnackBar(SnackBar(content: Text(error)));
    }
  },
),
/* ... */

I still dispatched my AuthError action so I could have a log of the actual errors, as you'd most likely want to return/show a custom error instead of the one you get.

@brianegan
Copy link
Owner

OnWillChange now supports new and old viewmodel, also adde example to latest version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants