Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

goncalo-diaas's avatar

Livewire Component

I'm creating a Livewire component to page through a multi-step questionnaire. When I try to access the $surveyQuestions information, it's always undefined. What am I doing wrong?

<?php
namespace App\Livewire\Forms;

use Livewire\Component;
use App\Models\SurveyQuestion;

class SurveyForm extends Component
{
    public $currentPage = 1;
    public $formData = [];

    public function mount()
    {
        $surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
    }

    public function nextPage()
    {
        $this->currentPage++;
    }

    public function previousPage()
    {
        $this->currentPage--;
    }

    public function submitForm()
    {
        // Handle form submission
    }
}
?>

<div>
    @foreach ($surveyQuestions as $question)
        {{ $question->text }}
        <!-- Display question options or input fields here -->
    @endforeach

    <button wire:click="previousPage">Previous</button>
    <button wire:click="nextPage">Next</button>
</div>
0 likes
12 replies
tykus's avatar

You have only defined $surveyQuestions in the scope of the mount method; make it instance state instead:

public Collection $surveyQuestions;
public function mount()
{
    $this->surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
}
goncalo-diaas's avatar

I get the same error unfortunately

<?php

namespace App\Livewire\Forms;

use Livewire\Component;
use App\Models\SurveyQuestion;

class SurveyForm extends Component
{
    public $currentPage = 1;
    public $formData = [];
    public Collection $surveyQuestions;

    public function mount()
    {
        $this->surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
    }

    public function nextPage()
    {
        $this->currentPage++;
    }

    public function previousPage()
    {
        $this->currentPage--;
    }

    public function submitForm()
    {
        // Handle form submission
    }
}
?>

<div>
    @foreach ($surveyQuestions as $question)
        {{ $question->text }}
        <!-- Display question options or input fields here -->
    @endforeach

    <button wire:click="previousPage">Previous</button>
    <button wire:click="nextPage">Next</button>
</div>

tykus's avatar

Is it undefined, or just an empty Collection?

Aside, the correct (FQCN) type-hint for the property will be \Illuminate\Database\Eloquent\Collection

goncalo-diaas's avatar

@tykus

Yes its undefined, when i load the view with the component i get the variable $surveyQuestions undefined, but when i try to dump the info from SurveyQuestion i can found it.

<?php

namespace App\Livewire\Forms;

use Livewire\Component;
use App\Models\SurveyQuestion;
use Illuminate\Database\Eloquent\Collection;

class SurveyForm extends Component
{
    public $currentPage = 1;
    public $formData = [];
    public Collection $surveyQuestions;

    public function mount()
    {
        $this->surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
    }

    public function nextPage()
    {
        $this->formData[$this->currentPage] = request()->all();
        $this->currentPage++;
    }

    public function previousPage()
    {
        $this->currentPage--;
    }

    public function submitForm()
    {
        // Handle form submission
    }
}
?>

<div>
    @foreach ($surveyQuestions as $question)
        {{ $question->text }}
        <!-- Display question options or input fields here -->
    @endforeach

    <button wire:click="previousPage">Previous</button>
    <button wire:click="nextPage">Next</button>
</div>
tykus's avatar

@goncalo-diaas strange; can you show how you are using the component (Route / parent view template)?

goncalo-diaas's avatar

@tykus

Sure

resources/views/survey/index.blade.php

<x-guest-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
            {{ $url }}
        </h2>
    </x-slot>
    <div class="py-12">
        <div class="max-w-full mx-auto sm:px-6 lg:px-8 space-y-10">
            <div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 text-gray-900 dark:text-gray-100">
                    <div class="container h-100">
                        <div class="row h-100 justify-content-center align-items-center">
                            
                            <livewire:survey-form />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</x-guest-layout>

resources/views/livewire/survey-form.blade.php

<?php

namespace App\Livewire\Forms;

use Livewire\Component;
use App\Models\SurveyQuestion;
use Illuminate\Database\Eloquent\Collection;

class SurveyForm extends Component
{
    public $currentPage = 1;
    public $formData = [];
    public Collection $surveyQuestions;

    public function mount()
    {
        $this->surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
        dd($this->surveyQuestions);
    }

    public function nextPage()
    {
        if($this->currentPage == null) {
            $this->formData[$this->currentPage] = request()->all();
        }
        $this->currentPage++;
    }

    public function previousPage()
    {
        $this->currentPage--;
    }

    public function submitForm()
    {
        // Handle form submission
    }
}
?>

<div>
    @foreach ($surveyQuestions as $question)
        {{ $question->text }}
        <!-- Display question options or input fields here -->
    @endforeach

    <button wire:click="previousPage">Previous</button>
    <button wire:click="nextPage">Next</button>
</div>

Routes that i use for this

Route::group(['prefix' => 'surveys', 'middleware' => 'auth'], function () {
    Route::get('/{survey}/manage', SurveyController::class . '@manage')->name('admin.surveys.manage');
    Route::put('/{survey}', SurveyController::class . '@update')->name('admin.surveys.update');
});

SurveyController.php

<?php

namespace App\Http\Controllers;

use App\Models\Question;
use App\Models\Survey;
use App\Models\SurveyQuestion;

class SurveyController extends Controller
{
    public function showSurvey($url) {
        if ($url != null) {
            $survey = Survey::where('url', $url)->first();
            $questions = $this->getQuestions($survey);
        } else {
            return redirect()->route('home');
        }

        return view('survey.index', compact('url', 'questions', 'survey'));
    }

    public function manage($survey) {
        $survey = Survey::find($survey);
        $questions = $this->getQuestions($survey);

        return view('admin.surveys.manage', compact('survey', 'questions'));
    }

    private function getQuestions($survey) {
        $surveyQuestions = SurveyQuestion::where('survey_id', $survey->id)->first();
        $questionIds = explode(',', $surveyQuestions->questions);

        return Question::whereIn('id', $questionIds)->get();
    }
}

I cant see where the problem is, i have updated Laravel and Livewire recently.

tykus's avatar

@goncalo-diaas wait... is this all one file???

<?php

namespace App\Livewire\Forms;

use Livewire\Component;
use App\Models\SurveyQuestion;
use Illuminate\Database\Eloquent\Collection;

class SurveyForm extends Component
{
    public $currentPage = 1;
    public $formData = [];
    public Collection $surveyQuestions;

    public function mount()
    {
        $this->surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
        dd($this->surveyQuestions);
    }

    public function nextPage()
    {
        if($this->currentPage == null) {
            $this->formData[$this->currentPage] = request()->all();
        }
        $this->currentPage++;
    }

    public function previousPage()
    {
        $this->currentPage--;
    }

    public function submitForm()
    {
        // Handle form submission
    }
}
?>

<div>
    @foreach ($surveyQuestions as $question)
        {{ $question->text }}
        <!-- Display question options or input fields here -->
    @endforeach

    <button wire:click="previousPage">Previous</button>
    <button wire:click="nextPage">Next</button>
</div>
tykus's avatar
tykus
Best Answer
Level 104

@goncalo-diaas yep.

Make a separate file in App\Livewire namespace for SurveyForm class

goncalo-diaas's avatar

@tykus

Already do that but doesnt work too, i need to make some more change in this code? I dont need some type of return?

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\SurveyQuestion;
use Illuminate\Database\Eloquent\Collection;

class SurveyForm extends Component
{
    public $currentPage = 1;
    public $formData = [];
    public Collection $surveyQuestions;

    public function mount()
    {
        $this->surveyQuestions = SurveyQuestion::where('survey_id', 70)->get();
        dd($this->surveyQuestions);
    }

    public function nextPage()
    {
        if($this->currentPage == null) {
            $this->formData[$this->currentPage] = request()->all();
        }
        $this->currentPage++;
    }

    public function previousPage()
    {
        $this->currentPage--;
    }

    public function submitForm()
    {
        // Handle form submission
    }
}
?>
tykus's avatar

@goncalo-diaas checking that the view template is in the correct directory resources/views/livewire/survey-form.blade.php?

You can get rid of the dd in the `mount method

What error message (if any) do you see now?

1 like

Please or to participate in this conversation.