skip to Main Content

I am building a demo quiz app in flutter using Bloc, The data is shown and I am trying to update the question and it’s options. The widget isn’t rebuilding I think. Everytime i click on a option, it should move to the next question, but it doesn’t show any changes in the UI. it changes the question after I press hot reload.

class QuizCubit extends Cubit<QuizState> {
  QuizCubit() : super(QuizInitialState()) {
    drawQuizData();
  }
  QuizBrain quizBrain = QuizBrain();
  late QuizResult result;

  drawQuizData() async {
    emit(QuizLoadingDemoState());
    await Future.delayed(
      const Duration(seconds: 1),
    );
    emit(QuizDataState(
      quizBrain: quizBrain,
    ));
  }

  void pickedOption() {
    quizBrain.toNextQuestion();
    if (quizBrain.isLastQuestion()) {
      emit(QuizQuizCompletedState());
    } else {
      emit(QuizPickedOptionState());
    }
  }
}


pickedOption

is the function responsible
The quiz logic is fine as it is working without bloc without any issues.

Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            BlocConsumer<QuizCubit, QuizState>(
              listener: (context, state) {
                if (state is QuizQuizCompletedState) {
                  // Handle quiz completion here.
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: const Row(
                        children: [
                          Icon(
                            Icons.info_outline,
                            color: Colors.white,
                          ),
                          SizedBox(width: 12.0),
                          Text(
                            "Success",
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 16.0,
                                fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                      backgroundColor: Colors.green.shade300,
                      duration: const Duration(seconds: 3),
                      action: SnackBarAction(
                        label: 'Close',
                        textColor: Colors.white,
                        onPressed: () {
                          // Add any action you want here
                          ScaffoldMessenger.of(context).hideCurrentSnackBar();
                        },
                      ),
                    ),
                  );
                }
              },
              listenWhen: (previous, current) => current is QuizActionState,
              bloc: quizCubit,
              buildWhen: (previous, current) => current is! QuizActionState,
              builder: (context, state) {
                if (state is QuizLoadingDemoState) {
                  return const CupertinoActivityIndicator();
                }
                if (state is QuizPickedOptionState) {
                  // emit();
                  return const CircularProgressIndicator();
                }
                if (state is QuizDataState) {
                  return Column(
                    children: [
                      Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            "${state.quizBrain.questionNumber + 1}: ",
                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),
                          Text(
                            state.quizBrain.quizQuestion(),
                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                      SizedBox(
                        height: 120,
                        width: 210,
                        child: ListView.builder(
                          itemCount: state.quizBrain.quizOptions().length,
                          itemBuilder: (context, index) {
                            return GestureDetector(
                              onTap: () {
                                //   quizCubit.pickedOption(
                                //   state.quizBrain.quizOptions()[index],
                                // );
                                quizCubit.pickedOption(
                                    );
                              },
                              child: Text(
                                state.quizBrain.quizOptions()[index],
                                style: const TextStyle(
                                    fontWeight: FontWeight.bold),
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  );
                }
                return const Text("123");
              },
            ),
          ],
        ),
      ),
    );



quizCubit.pickedOption(
                                        );

2

Answers


  1. Chosen as BEST ANSWER

    I solved the answer myself. The answer to it is instead of emitting the new state, I just emitted the old state again.

    Here is the code for it.

    void pickedOption() {
        quizBrain.toNextQuestion();
        if (quizBrain.isLastQuestion()) {
          quizBrain.reset();
          emit(QuizQuizCompletedState());
        } else {
          emit(QuizDataState(quizBrain: quizBrain));
        }
      }
    

  2. Your issue seems to be from the state management in your QuizCubit. When you call the pickedOption function, you are updating the QuizBrain object, but this doesn’t necessarily trigger a re-render of the widget because you’re only emitting the QuizPickedOptionState() or the QuizQuizCompletedState() without carrying over the updated data.

    Here are a few steps you can take to resolve this issue:

    1. Modify the States to Include the Updated Data: Every time you emit a new state from the QuizCubit, make sure it carries the updated data. For instance, you could include the updated QuizBrain object in both the QuizPickedOptionState and QuizQuizCompletedState.
    class QuizPickedOptionState extends QuizState {
      final QuizBrain quizBrain;
      QuizPickedOptionState({required this.quizBrain});
    }
    
    class QuizQuizCompletedState extends QuizState {
      final QuizBrain quizBrain;
      QuizQuizCompletedState({required this.quizBrain});
    }
    
    1. Emit the States with the Updated Data:

    Update your pickedOption method to include the updated quizBrain:

    void pickedOption() {
      quizBrain.toNextQuestion();
      if (quizBrain.isLastQuestion()) {
        emit(QuizQuizCompletedState(quizBrain: quizBrain));
      } else {
        emit(QuizPickedOptionState(quizBrain: quizBrain));
      }
    }
    
    1. Update the Widget Rendering Logic:

    Now, in your BlocConsumer, you should account for the states you modified:

    //...
    builder: (context, state) {
      if (state is QuizLoadingDemoState) {
        return const CupertinoActivityIndicator();
      }
      if (state is QuizPickedOptionState || state is QuizDataState || state is QuizQuizCompletedState) {
        var quizBrainToUse = state is QuizDataState 
            ? state.quizBrain 
            : (state is QuizPickedOptionState ? state.quizBrain : null);
            
        // Return your UI here using `quizBrainToUse`.
        // ...
      }
      return const Text("123");
    }
    //...
    

    With these changes, your widget should be able to re-render and show updated data whenever there’s a state change in your QuizCubit.

    Lastly, ensure that the methods within QuizBrain (e.g., toNextQuestion, quizQuestion, and quizOptions) are functioning correctly and returning the expected data.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search