Unhandled error LateInitializationError: Local 'failureOrSuccess' has not been initialized. occurred in Instance of 'SignInFormBloc'

Issue

Stream<SignInFormState> _performActionOnAuthFacadeWithEmailAndPassword(
Future<Either<AuthFailure, Unit>> Function({
  @required EmailAddress emailAddress,
  @required Password password,
})
    forwardedCall,
) async* {
Either<AuthFailure, Unit> failureOrSuccess;

final isEmailValid = state.emailAddress.isValid();
final isPasswordValid = state.password.isValid();

if (isEmailValid && isPasswordValid) {
  yield state.copyWith(
    isSubmitting: true,
    authFailureOrSuccessOption: none(),
  );

  failureOrSuccess = await forwardedCall(
    emailAddress: state.emailAddress,
    password: state.password,
  );
}

yield state.copyWith(
  isSubmitting: false,
  showErrorMessages: true,
  authFailureOrSuccessOption: optionOf(failureOrSuccess),
);

}

This worked fine in Resocoder’s DDD tutorial But ever since the Flutter’s NNBD, we are required to add the late keyword in

Either<AuthFailure, Unit> failureOrSuccess;

and so it changes to:

late Either<AuthFailure, Unit> failureOrSuccess;

Now the error in the:

yield state.copyWith(
isSubmitting: false,
showErrorMessages: true,
authFailureOrSuccessOption: optionOf(failureOrSuccess),
);

goes away since we added the late keyword.

However, we get the following error when we test out the email address validation in the form. So instead of getting a red alert in TextFormField we get the following error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Unhandled error 
LateInitializationError: Local 'failureOrSuccess' has not been initialized. occurred in 
Instance of 'SignInFormBloc'.

Removing the late keyword in the Either<AuthFailure, Unit> failureOrSuccess; throws the same error again, due to null-safety being defaulted in Flutter SDK.

I tried degrading flutter and many more things but there seems to be no workaround.
Can anyone help?

Solution

Okay so found the answer to the problem just replace the following code:

Stream<SignInFormState> _performActionOnAuthFacadeWithEmailAndPassword(
Future<Either<AuthFailure, Unit>> Function({
  @required EmailAddress emailAddress,
  @required Password password,
})
    forwardedCall,
) async* {
Either<AuthFailure, Unit> failureOrSuccess;

final isEmailValid = state.emailAddress.isValid();
final isPasswordValid = state.password.isValid();

if (isEmailValid && isPasswordValid) {
  yield state.copyWith(
    isSubmitting: true,
    authFailureOrSuccessOption: none(),
  );

  failureOrSuccess = await forwardedCall(
    emailAddress: state.emailAddress,
    password: state.password,
  );
}

yield state.copyWith(
  isSubmitting: false,
  showErrorMessages: true,
  authFailureOrSuccessOption: optionOf(failureOrSuccess),
);
}

with:

Stream<SignInFormState> _performActionOnAuthFacadeWithEmailAndPassword(
Future<Either<AuthFailure, Unit>> Function({
  required EmailAddress emailAddress,
  required Password password,
})
    forwardedCall,
) async* {
Either<AuthFailure, Unit> failureOrSuccess;

final isEmailValid = state.emailAddress.isValid();
final isPasswordValid = state.password.isValid();

if (isEmailValid && isPasswordValid) {
  yield state.copyWith(
    isSubmitting: true,
    authFailureOrSuccessOption: none(),
  );

  failureOrSuccess = await forwardedCall(
    emailAddress: state.emailAddress,
    password: state.password,
  );
  yield state.copyWith(
    isSubmitting: false,
    showErrorMessages: AutovalidateMode.always,
    authFailureOrSuccessOption: optionOf(failureOrSuccess),
  );
} else {
  yield state.copyWith(
    isSubmitting: false,
    showErrorMessages: AutovalidateMode.always,
    authFailureOrSuccessOption: none(),
  );
}
}

here you won’t require the late keyword as the if-else condition is calling the failureOrSuccess variable and so in every case, failureOrSuccess is getting some value, in else condition it is none(). The code works fine for now, as we still get the red alerts in the Form UI when we try to make an invalid signin.

I will update my answer in case I find a better alternative.

PS: My environment in pubspec.yaml file:

environment:
 sdk: ">=2.12.0 <3.0.0"

Answered By – Somanshu Singh

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *