questions and answer choices do not match in the next question

54 Views Asked by At

I have a code where the code is displayed like a quiz, but the strange thing is that the first question is the question and the answer choices match but the next question the questions and answer choices don't match and the next questions are the same, only the first question matches, and questions 2, 3 .4 and so on don't even match.

for example : The question asks for year xxxx but the answer option displays the street location answer The next question is the same, only the first question and answer choice match

displays the question according to the answer choices so that the questions and answer choices in the next question match.

here the code for mount():

public function mount($uid)
    {

        $sessionKey = 'quiz_' . auth()->user()->id;
        if (session()->has($sessionKey)) {
            $sessionData = session($sessionKey);
            $this->questionIndex = $sessionData['questionIndex'] ?? 0;
        } else {
            $this->questionIndex = 0;
        }

        // get exams id 
        $getid = Exams::where('uid', $uid)->firstorFail();
        // get data         
        $this->getExamName = $getid->name;
        $this->getDuration = $getid->duration;
        $this->getExamDescription = $getid->short_description;
        $this->getTypeExam = $getid->type;
        $this->getFinalAssessmentExams = $getid->final_assessment;

        // take exams 
        $takeExams = TakeExams::where('exams_id', $getid->id)->first();
        $this->get_id_expire = $takeExams->id;

        // get questions
        $questions = Questions::where('exam_id', $getid->id)->inRandomOrder()->get();

        // check question if it answered or not, if answered skip then show next question
        $answeredQuestions = Answers::where('user_id', Auth::user()->id)
            ->where('exam_id', $getid->id)
            ->pluck('question_id')
            ->toArray();

        $this->questions = $questions->whereNotIn('id', $answeredQuestions);

        // Set nilai $questionIndex ke pertanyaan terakhir yang dijawab
        $lastAnsweredQuestion = Answers::where('user_id', Auth::user()->id)
            ->where('exam_id', $getid->id)
            ->orderBy('id', 'desc')
            ->first();

        // check last answer 
        if ($lastAnsweredQuestion) {
            $lastAnsweredQuestionIndex = $this->questions->pluck('id')->search($lastAnsweredQuestion->question_id);
            if ($lastAnsweredQuestionIndex !== false) {
                $this->questionIndex = $lastAnsweredQuestionIndex + 1;
            }
        }

        // get data 
        $this->exams_id = $getid->id;
        $this->takeExams = $takeExams->id;

        foreach ($this->questions as $key => $questionOption) {
            $this->questionOption[$key]['options'] = QuestionsOption::where('questions_id', $questionOption->id)->get();
            // return $this->questions[$key]['options'];
            // If the current question matches the desired question index, assign its name to $name
            if ($key === $this->questionIndex) {
                $this->answer = $questionOption['question_option_id'];
                $this->exams_id = $getid->id;
                $this->takeExams = $takeExams->id;
            }
        }
    }

here the code for submitQuiz

public function submitQuiz()
    {
        $validated = $this->validate([
            'answer' => 'required',
        ]);

        session(['quiz_' . auth()->user()->id => [
            'questionIndex' => $this->questionIndex,
            // Simpan status kuis lainnya yang perlu Anda pertahankan di sini
        ]]);


        // get record question option by id 
        $getOption = QuestionsOption::where('id', $this->answer)->first();
        // dd($getOption);

        if ($validated) {
            // creating answer
            Answers::create([
                'user_id' => Auth::user()->id,
                'question_id' => $getOption->questions_id,
                'question_option_id' => $this->answer,
                'exam_id' => $this->exams_id,
                'take_exam_id' => $this->takeExams,
                'multiple_choice_answer' => $getOption->name,
                'is_correct' => $getOption->is_correct_answer,
            ]);
        }

        // quiz 
        $this->questionIndex++;
        if ($this->questionIndex >= count($this->questions)) {
            $this->finished = true;
            // session 
            $sessionKey = 'quiz_' . auth()->user()->id;
            session()->forget($sessionKey);
            $this->dispatch('remove-from-local-storage', ['key' => 'expiry']);

            // count the correct answer 
            $correctAnswersCount = Answers::where('take_exam_id', $this->takeExams)
                ->where('is_correct', '1')
                ->count();

            // update number of correct answer from take_exams so late can be use to make score
            TakeExams::where('id', $this->takeExams)
                ->update(['number_of_correct_answer' => $correctAnswersCount]);
        } else {
            $this->question = $this->questions[$this->questionIndex];
            $this->answer = null;

            $this->resetRadioOptions();

            // count the correct answer 
            $correctAnswersCount = Answers::where('take_exam_id', $this->takeExams)
                ->where('is_correct', '1')
                ->count();

            // update number of correct answer from take_exams so late can be use to make score
            TakeExams::where('id', $this->takeExams)
                ->update(['number_of_correct_answer' => $correctAnswersCount]);
        }
    }

and for last, the code for view

<form wire:submit.prevent="submitQuiz">
                                    @csrf
                                    <div class="">
                                        @if (isset($questions[$questionIndex]))
                                            <span class="text-sm text-gray-400 italic ">{{ __('Question :') }}</span>
                                            <div class="text-3xl w-full">
                                                <div class="text-3xl w-full">
                                                    {{ $questions[$questionIndex]['name'] }}
                                                </div>
                                            </div>
                                        @endif

                                        <div class="shadow-md rounded-md bg-gray-200">
                                            @foreach ($questionOption[$questionIndex]['options'] as $option)
                                                <label for="answer-{{ $option->id }}"
                                                    class="flex text-gray-700 rounded-md px-3 py-2 my-3  hover:bg-indigo-300 cursor-pointer ">
                                                    <input type="radio" wire:model="answer" name="answer"
                                                        value="{{ $option->id }}" id="answer-{{ $option->id }}"
                                                        @if ($this->answer == $option->id) checked @endif>
                                                    <span class="-mt-1 px-3">
                                                        {{ $option->name }}
                                                    </span>
                                                </label>
                                                <p class="text-xs italic text-red-500 ml-7">
                                                    @error('answer')
                                                        {!! "<span class='superscript'>* </span>" . $message !!}
                                                    @enderror
                                                </p>
                                            @endforeach
                                        </div>
                                    </div>
                                    <div class="mt-4">
                                        @if ($questionIndex >= count($questions))
                                            <div>
                                                <div class="bg-white p-3 ">
                                                    {{ __('If you refreshed the page, ') }} <span class="text-red-500">
                                                        {{ __('refresh') }} </span>
                                                    {{ __('again until get the question left, or best you do') }} <span
                                                        class="text-red-500"> {{ __('re-take') }}</span>
                                                    {{ __('the exams from begining again.') }}
                                                </div>
                                                <div class="bg-white p-3 mt-4 ">
                                                    {{ __('If the question reach ') }} <span class="text-red-500">
                                                        {{ __('0') }} </span>
                                                    {{ __('then you have finish the exams.') }}
                                                </div>
                                                <div class="my-3">
                                                    <x-green-button
                                                        wire:click="redirectToRoute('{{ route('student.exams-list') }}')"
                                                        class="w-full justify-center">{{ __('View Score') }}</x-green-button>
                                                </div>
                                                <div class="my-3">
                                                    <div class="w-full justify-center">
                                                        <x-primary-button onclick="goBack()"
                                                            class="w-full justify-center">{{ __('Back to Course') }}</x-primary-button>
                                                    </div>
                                                </div>
                                                <div class="my-3">
                                                    <x-indigo-button
                                                        wire:click="redirectToRoute('{{ route('student.dashboard') }}')"
                                                        class="w-full justify-center">{{ __('Back To Student Panel') }}</x-indigo-button>
                                                </div>
                                            </div>
                                        @else
                                            @if (isset($questions[$questionIndex]))
                                                <x-sky-button>
                                                    {{ __('Next Question') }}
                                                </x-sky-button>
                                            @else
                                                <div class="bg-white p-3 ">
                                                    {{ __('If you refreshed the page') }}
                                                    <span class="text-red-500">
                                                        {{ __('refresh') }} </span>
                                                    {{ __('again until get the question left. event you get error just refresh the page untiil finis the exams or do re-take the exams') }}
                                                </div>
                                            @endif
                                        @endif
                                    </div>
                                </form>
1

There are 1 best solutions below

1
Pippo On

Add a unique wire:key to the contents of the @foreach loop to allow Livewire to correctly update the page fragment, it is also advisable to enclose all contents in a root tag like a <div>

@foreach ($questionOption[$questionIndex]['options'] as $option)

   <div wire:key"answer-{{ $option->id }}"

      <label ....>
         ....
      </label>

      <p>
         ....
      </p>

   </div>

@endforeach

Here some reference