Skip to content
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

Error with copyWith in sign_in_form_bloc.dart #11

Open
Daniel203 opened this issue Apr 30, 2020 · 7 comments
Open

Error with copyWith in sign_in_form_bloc.dart #11

Daniel203 opened this issue Apr 30, 2020 · 7 comments
Assignees

Comments

@Daniel203
Copy link

The copyWith() method doesn't work inside sign_in_form_bloc.dart.
The state doesn't change when the user types the email or password inside the UI form.
The event is properly working and contains the changed value, but I can't add this value to the state.
The state remains in initial form even after the copyWith().

Annotazione 2020-04-30 112620

@ResoDev
Copy link
Contributor

ResoDev commented May 4, 2020

Hello! This is extremely strange because copyWith is implemented by freezed code gen and it has always worked for me.
Does it still happen even after you regenerate code by running flutter pub run build_runner build --delete-conflicting-outputs?

@ResoDev ResoDev self-assigned this May 4, 2020
@Daniel203
Copy link
Author

Thanks for your answer.
Yes, I've already executed the command. I've also tried changing the freezed version, using both the one present in your project and the latest version.
The strange thing is that if I try to print state.copyWith( ... ), in the console I can see the status updated with the data present in the event, but despite this, the bloc status doesn't change.
I really don't know what the problem could be.

@yakou32
Copy link

yakou32 commented May 4, 2020 via email

@darozarena
Copy link

darozarena commented May 5, 2020

Hello! Same problem here...
I have also another error when starting the app and calling SignInFormState.initial() with EmailAddress('') and Password(''). Both value objects try to execute the validation of the input and return Left(...). Here is the stacktrace:

I/flutter ( 9950): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9950): The following Left<ValueFailure<dynamic>, dynamic> object was thrown building
I/flutter ( 9950): BlocConsumer<SignInFormBloc, SignInFormState>(dirty):
I/flutter ( 9950):   Left(ValueFailure<dynamic>.invalidEmail(failedValue: ))
I/flutter ( 9950):
I/flutter ( 9950): The relevant error-causing widget was:
I/flutter ( 9950):   BlocConsumer<SignInFormBloc, SignInFormState>

@darozarena
Copy link

Hello! Same problem here...
I have also another error when starting the app and calling SignInFormState.initial() with EmailAddress('') and Password(''). Both value objects try to execute the validation of the input and return Left(...). Here is the stacktrace:

I/flutter ( 9950): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9950): The following Left<ValueFailure<dynamic>, dynamic> object was thrown building
I/flutter ( 9950): BlocConsumer<SignInFormBloc, SignInFormState>(dirty):
I/flutter ( 9950):   Left(ValueFailure<dynamic>.invalidEmail(failedValue: ))
I/flutter ( 9950):
I/flutter ( 9950): The relevant error-causing widget was:
I/flutter ( 9950):   BlocConsumer<SignInFormBloc, SignInFormState>

I found my error. I was throwing left(...) in value_validators.dart instead of return it 😅

@Daniel203
Copy link
Author

Trying to follow this example (https://github.com/felangel/bloc/tree/master/examples/flutter_login), I finally found the cause of the problem.
Problems are EmailAddress and Password classes inside the bloc state.
I've seen that replacing them with String, the copyWith() method works correctly.

Then I had to add two more parameters (isEmailValid, isPasswordValid) to the state that check if the data are valid.
The way I check if a data is valid is not very nice. It would have been better to create methods that check the data directly inside sign_in_form_bloc.dart but to reuse the code and keep it as close as possible to the initial project, I did it this way.

This is my solution.
(I know this isn't the right solution, but it's more like a temporary fix.)

sign_in_form_state.dart

part of 'sign_in_form_bloc.dart';

@freezed
abstract class SignInFormState with _$SignInFormState {
  const factory SignInFormState({
    @required String emailAddress,
    @required String password,
    @required bool isEmailValid,
    @required bool isPasswordValid,
    @required bool showErrorMessage,
    @required bool isSubmitting,
    @required Option<Either<AuthFailure, Unit>> authFailureOrSuccessOption, 
  }) = _SignInFormState;

  factory SignInFormState.initial() => SignInFormState(
    emailAddress: '',
    password: '',
    isEmailValid: false,
    isPasswordValid: false,
    showErrorMessage: false,
    isSubmitting: false,
    authFailureOrSuccessOption: none(),
  );
}

sign_in_form_bloc.dart

...
@override
  Stream<SignInFormState> mapEventToState(
    SignInFormEvent event,
  ) async* {
    yield* event.map(
      emailChanged: (e) async* {
        yield state.copyWith(
          emailAddress: e.emailStr,
          isEmailValid: EmailAddress(e.emailStr).isValid(),
          authFailureOrSuccessOption: none(),
        );
      }, 
      passwordChanged: (e) async* {
        yield state.copyWith(
          password: e.passwordStr,
          isPasswordValid: Password(e.passwordStr).isValid(),
          authFailureOrSuccessOption: none(),
        );
      },
...

@TezzaMichael
Copy link

danke @Daniel203

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

No branches or pull requests

5 participants