Home > Software design >  Error "Trying to get non-object property" after calling a livewire function
Error "Trying to get non-object property" after calling a livewire function

Time:08-03

I'm using livewire to call a function that turns the user's role into "writer", the function in the livewire class is as follows :

class User extends Component
{
    public $users;

    public function turnWriter($id){
        DB::table('users')->where('id', $id)->update(['role' => 'writer']);
    }

    public function render()
    {
        return view('livewire.user');
    }
}

calling the function on the blade template on the button inside the if statement at the end:

    <thead >
      <tr>
        <th scope="col" >
          Username
        </th>
        <th scope="col" >
          Email
        </th>
        <th scope="col" >
          Verified At
        </th>
        <th scope="col" >
          Actions
        </th>
        <th scope="col" >
        </th>
      </tr>
    </thead >
    <tbody>
        @foreach ($users as $user)
        <tr >
            <td >
                {{$user->name}}
            </td>
            <td >
                {{$user->email}}
            </td>
            @if(empty($user->email_verified_at))
            <td >
                Not Verified yet   
            @else
            <td >
            {{$user->email_verified_at}}
            @endif
            </td>
            <td >
                Block
            </td>
            @if($user->role == 'user')
            <td>
                <div>
                    <button wire:click="turnWriter({{ $user->id }})" >
                        Make Writer  
                    </button>
                </div>
            </td>          
            @else
            <td >
                
                    Remove Writer role
                
            </td>
            @endif   
        </tr >
        @endforeach                     
    </tbody>
</table>                   

the controller function that returns the blade view:

    public function dashboard(){
        $users = DB::table('users')->where('role', 'user')->Orwhere('role', 'writer')->get();
        //dd($users);
        return view('users.dashboard',[
            'users' => $users,
        ]);
    }

The issue is, when clicking the button, the user's role does get changed to "writer" in the database, the problem comes afterwards, the view can't read the value or the property of $user for some reason and the following error pops up, the function however works just fine:

Error

CodePudding user response:

Livewire does not like stdClass variables. It only supports the types mentioned here. When you use a DB::get(), you get a collection of stdClass, and upon rehydrating the component (as what happens when you add a role to the user), it will convert all of the data to arrays. So, either always cast toArray() so you have an expected result set (and then don't use ->name, but ['name']), or use model collections.

I'd like to add that it's best practice to keep variables inside Livewire components, instead of having them in the main blade. If you don't need the $users variable in your dashboard.blade, then I highly suggest moving it to your component (in the mount method, for example)

CodePudding user response:

I haven't used livewire but don't you think you should pass an argument to view? The $users variable is null in your case if you don't pass it.

public function render()
{
    return view('livewire.user', [
        'users' => User::all(), //or User::where('role', 'writer')->get(); depending on your logic
    ]);
}
  • Related