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

Bloc getting value error #1266

Closed
gerryau opened this issue Jun 8, 2020 · 6 comments
Closed

Bloc getting value error #1266

gerryau opened this issue Jun 8, 2020 · 6 comments
Assignees
Labels
question Further information is requested
Projects

Comments

@gerryau
Copy link

gerryau commented Jun 8, 2020

Describe the bug
Error saying string value of a bloc state is empty, but the desired result is achieved on device when running.

Expected behavior
No error.

════════ Exception caught by widgets library ═══════════════════════════════════
The following UnexpectedValueError was thrown building BlocBuilder<TodoTimerBlockFormBloc, TodoTimerBlockFormState>(dirty, state: _BlocBuilderBaseState<TodoTimerBlockFormBloc, TodoTimerBlockFormState>#f5386):
"Encountered a ValueFailure at an unrecoverable point. Terminating. Failure was: ValueFailure.empty(failedValue: )"

The relevant error-causing widget was
BlocBuilder<TodoTimerBlockFormBloc, TodoTimerBlockFormState>
package:app/…/todo_timer_form/new_todo_timer_form_page.dart:69
When the exception was thrown, this was the stack
#0 ValueObject.getOrCrash.
package:app/…/core/value_objects.dart:21
#1 Left.fold
package:dartz/src/either.dart:124
#2 ValueObject.getOrCrash
package:app/…/core/value_objects.dart:21
#3 TimerFormScaffold.build.
package:app/…/todo_timer_form/new_todo_timer_form_page.dart:71
#4 BlocBuilder.build
package:flutter_bloc/src/bloc_builder.dart:90
...
════════════════════════════════════════════════════════════════════════════════

@Injectable
class TodoTimerBlockFormBloc
extends Bloc<TodoTimerBlockFormEvent, TodoTimerBlockFormState> {
final ITodoRepository _todoRepository;

TodoTimerBlockFormBloc(this._todoRepository);

@OverRide
TodoTimerBlockFormState get initialState => TodoTimerBlockFormState.initial();

@OverRide
Stream mapEventToState(
TodoTimerBlockFormEvent event,
) async* {
yield* event.map(
initialized: (e) async* {
yield e.initialTodoOption.fold(
() => state,
(initialTodo) {
return state.copyWith(
todo: initialTodo,
);
},
);
},
...

class NewTimerPage extends HookWidget {
final TodoItem selectedTodo;

const NewTimerPage({
Key key,
@required this.selectedTodo,
}) : super(key: key);

@OverRide
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => getIt()
..add(TodoTimerBlockFormEvent.initialized(optionOf(selectedTodo))),
child: BlocConsumer<TodoTimerBlockFormBloc, TodoTimerBlockFormState>(
listener: (context, state) {
...
builder: (context, state) {
return Stack(
children: [
TimerFormScaffold(),
],
);
}
),
);
}
}

class TimerFormScaffold extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: BlocBuilder<TodoTimerBlockFormBloc, TodoTimerBlockFormState>(
builder: (context, state){
return Text(state.todo.name.getOrCrash());
},
)
),
);
}
}

@felangel
Copy link
Owner

felangel commented Jun 8, 2020

Hi @gerryau 👋
Thanks for opening an issue!

Can you please provide a link to a sample app which reproduces the issue? Thanks 🙏

@felangel felangel self-assigned this Jun 8, 2020
@felangel felangel added question Further information is requested waiting for response Waiting for follow up labels Jun 8, 2020
@felangel felangel added this to To do in bloc via automation Jun 8, 2020
@gerryau
Copy link
Author

gerryau commented Jun 9, 2020

Hey @felangel thanks for your reply, I've just invited you to see the app, where the problem exists. It's under the todo-timer branch. Thanks

@felangel
Copy link
Owner

felangel commented Jun 9, 2020

Hi @gerryau I am unable to run due to a missing GoogleService-Info.plist. Would it be possible for you to put together a simple sample app which ideally doesn't have a Firebase dependency and reproduces the issue? It would be much easier for me to help if I can easily reproduce the issue locally, thanks!

@gerryau
Copy link
Author

gerryau commented Jun 9, 2020

No problem @felangel , see link: https://github.com/gerryau/todo-bloc

@felangel
Copy link
Owner

Hey @gerryau 👋

I took a look and the issue is there is a frame where the TodoTimerState is TodoTimerState.initial() which means that when you call state.todo.name.getOrCrash() it will crash since the todo is empty. This is because the bloc's initial state is TodoTimerState.initial() and when you add the TodoTimerEvent.initialized event it still takes a frame to propagate so the TimerFormScaffold will be rendered at least once where the state has not been updated.

I opened a pull request with one potential fix. Hope that helps!

Closing for now but feel free to comment with additional questions and I'm happy to continue the conversation 👍

bloc automation moved this from To do to Done Jun 10, 2020
@felangel felangel removed the waiting for response Waiting for follow up label Jun 10, 2020
@constantinLu

This comment was marked as duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
bloc
  
Done
Development

No branches or pull requests

3 participants