Search code examples
laravellaravel-bladealpine.jslaravel-10

Alpine JS - Showing item twice when declaring only one


I have a Blade template in Laravel that uses Alpine JS.

I have a questions array that gets initialized with only one element, but for some reason there are two elements on screen.

What can be wrong?

Here's the code I'm using:

<x-guest-layout>
    <x-slot:title>
        {{ __('survey.create.title')  . ' - '. config('app.name', 'Riview') }}
    </x-slot>
        <div class="pb-6">
        <h2>
            {{ __('survey.questions.title') }}
        </h2>
        <h3>
           {{ $survey->name }}
        </h3>
        <form action="{{ route('survey.questions.store', $survey) }}" method="post" x-data="{
            questions: [{
                content: '',
                type: 'text'
            }],
            addQuestion() {
                this.questions.push({
                    content: '',
                    type: 'text'
                })
            },
            removeQuestion(index) {
                this.questions.splice(index, 1)
            }
        }">
            @csrf
            <div class="mb-4">
                <template x-for="(question, index) in questions" :key="index">
                    <div class="form-group py-4">
                        <div class="flex justify-between mb-2 items-center">
                            <h3>Question #<span x-text="index + 1"></span></h3>
                            <button x-show="questions.length > 1" type="button" class="btn btn-link" x-on:click="removeQuestion(index)">Remove</button>
                        </div>

                        <div class="mb-3">
                            <label :for="'question_'" x-bind:for="'question_' + index">Title</label>
                            <input type="text" x-model="question.content"
                                :name="'questions['+index+'][content]'"
                                class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
                        </div>

                        <div>
                            <label :for="'question'" x-bind:for="'question[' + index + '][type]'">Question Type</label>
                            <select class="select select-bordered w-full" x-model="question.type"
                                x-bind:name="'questions['+index+'][type]'">
                                class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
                                <option value="text">Text</option>
                                <option value="textarea">Long Text</option>
                                <option value="radio">Multiple Choice</option>
                                <option value="checkbox">Checkboxes</option>
                            </select>
                        </div>
                    </div>
                </template>
            </div>
            <div class="mb-4">
                <button type="button" class="btn btn-accent" x-on:click="addQuestion">
                    + Add Another Question
                </button>
            </div>
            <div class="mt-6 flex items-center justify-end gap-x-6">
                <button type="submit" class="btn btn-primary">Save</button>
            </div>
        </form>
        </div>

</x-guest-layout>

And here's the screenshot:

enter image description here


Solution

  • There are a number of possible reasons. 1.) check that you are not including alpineJs script multiple times by chance. 2.) include defer keyword in your alpineJs script as seen from this solution here