I don''t understand the question
Undefined Variable Livewire
Hello,
I am slowly transitioning to Livewire now and of course, what I could do in plain Laravel controller methods is now getting dificult to comprehend.
Here is my controller method, which shows the variables:
public function profile()
{
$id = Auth::user()->id;
$adminData = User::find($id);
return view('admin.admin_profile_view', compact('adminData'));
}
And in blade file, I can use it like this:
{{ $adminData->firstname }}
But now how can I use the same in livewire component , both the method and blade syntax ?
Thank you for help.
do you mean this? passing it into ...
<livewire:some-component :user=$adminData" />
@webrobert Thanks for your reply.
The question is:
How can I define and then compact variables in livewire ? And how to display the variables in blade file just like the example I showed above: {{ $adminData->firstname }}
as a livewire component
class ProfileShow extends component
{
public function render()
{
$adminData = Auth::user();
return view('admin.admin_profile_view', compact('adminData'));
}
}
but this isn't ideal when you have lots of renders and variables because each time the page renders everything has to be loaded again. Instead you use public properties.
https://laravel-livewire.com/docs/2.x/properties
and I am a particular fan of computed properties
https://laravel-livewire.com/docs/2.x/properties#computed-properties
so you could do...
class ProfileShow extends component
{
public $adminData; // also if you want to make the property reactive
// only fetch the user on the first render
public function mount()
{
$this->adminData = Auth::user();
}
public function render()
{
return view('admin.admin_profile_view'); // no need to pass it
}
}
}
and this works
{{ $adminData->firstname }}
and for a computed property
Computed properties are cached for an individual Livewire request lifecycle. Meaning, if you call
$this->post5 times in a component's blade view, it won't make a separate database query every time.
class ProfileShow extends component
{
public function getAdminDataProperty()
{
return auth()->user();
}
public function render()
{
return view('admin.admin_profile_view');
}
}
{{ $this->adminData->firstname }}
Hi Robert,
Thanks for your detailed explanation. I am still figuring out how it works. But the below one is showing blank page only:
class ProfileShow extends Component
{
public $user_id;
public $adminData;
public function mount()
{
$this->user_id = Auth::user()->id;
$this->adminData = User::find(id);
}
public function render()
{
return view('livewire.admin.profile-show', compact('adminData', 'user_id'));
}
}
@webrobert Yes those were comments, I checked and came up with this:
class ProfileShow extends Component
{
public $adminData;
public function mount()
{
$this->adminData = Auth::user();
}
public function render()
{
return view('admin.admin_profile_view');
}
}
Still, the page is blank. I have checked @livewireStyles, @livewireScripts are at proper places.
Do I need to change routes, its currently like this:
Route::middleware(['auth', 'role:Admin'])
->prefix('admin')
->as('admin.')
->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard');
Route::get('/logout', [AdminController::class, 'destroy'])->name('logout');
Route::get('/profile', [AdminController::class, 'profile'])->name('profile');
Route::post('/profile/store', [AdminController::class, 'profilestore'])->name('profile.store');
Route::get('/password/change', [AdminController::class, 'changepassword'])->name('change.password');
Route::post('/password/update', [AdminController::class, 'updatepassword'])->name('update.password');
});
@shunmas based on the code you've showed you are never using the livewire component. Do you have it in the view you load via your AdminController? Or are you wanting to just use a full page liveware component?
Hello Robert,
I installed livewire component like this:
composer require livewire/livewire
Then:
php artisan make:livewire Admin/ProfileShow
Then I used @livewirestyles and @livewirescripts at appropriate places.
Then I cut the div from admin_profile_view.blade.php and pasted it in livewire.admin.profile-show.blade.php and in its old place, I used @livewire('admin.profile-show').
And then the above Component class, I used this method as before:
class ProfileShow extends Component
{
public $adminData;
public function mount()
{
$this->adminData = Auth::user();
}
public function render()
{
return view('admin.admin_profile_view');
}
}
But unfortunately, the page is blank.
Basically I just want to update a certain part of the page, so the whole admin panel will be intact and only the main div, which is livewire component changes.
look you have to include the livewire components on the page your original admin blade was?
return view('admin.admin_profile_view');
on that page you have to add the Livewire component...
<livewire:profile-show />
@webrobert Yes I am showing it like this:
@livewire('admin.profile-show')
@shunmas hmmm, make sure you livewire blade has one root div, are there any errors the console? and what happens when you dd
public function render()
{
dd("I'm here");
return view('admin.admin_profile_view');
}
@webrobert 404 Not Found
The URL is 'admin/profile'
@webrobert Yes now when I changed the route to this, its working, showing dd I am here.
Route::get('/profile', ('\App\Http\Livewire\Admin\ProfileShow'))->name('profile');
```
ok, just confirming
the adminController view is... admin.admin_profile_view
AND
the livewire view is 'livewire.admin.profile-show'
@webrobert Yes, this is correct
Thank you for all your help. I highly appreciate you taking the time.
Given the fact that livewire is going to be like this for me, I have to revert back to normal laravel and not use livewire at all for this project.
Again, many thanks Bobby.
@shunmas sorry to hear that. I love livewire. My current project 99% livewire controllers.
@webrobert Its not that I disliked it, but I just want to show certain page using livewire. Sometimes the routes are not working, somethimes controller, then this new mount method. This is very time consuming.
@webrobert By the way, my admin master layout is like this (with livewire @ tags):
<!DOCTYPE html>
<html lang="en" class="light-style layout-menu-fixed" dir="ltr" data-theme="theme-default"
data-assets-path="{{ asset('backend/assets/') }}" data-template="vertical-menu-template-free">
<head>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<meta name="description" content="" />
<title>@yield('title') | {{ config('app.name') }}</title>
@include('repeating_sections.css_links')
@livewireStyles
</head>
<body>
<!-- Layout wrapper -->
<div class="layout-wrapper layout-content-navbar">
<div class="layout-container">
<!-- Menu -->
@include('admin.body.sidebar')
<div class="layout-page">
<!-- Navbar -->
@include('admin.body.header')
<!-- / Navbar -->
<!-- Content wrapper -->
<div class="content-wrapper">
<!-- Content -->
@yield('admin')
<!-- / Content -->
<!-- Footer -->
@include('admin.body.footer')
<!-- / Footer -->
<div class="content-backdrop fade"></div>
</div>
<!-- Content wrapper -->
</div>
<!-- / Layout page -->
</div>
</div>
@livewireScripts
@include('repeating_sections.js_links')
</body>
</html>
```
I was having a similar problem getting the page title to show up on a page. For the life of me I couldn't figure it out. I had only been using livewire for about 24 hours, lol.
I finally got it to work, so I posting this to maybe give you some ideas.
Here's my code:
<?php
namespace App\Livewire;
use Livewire\Component;
class Counter extends Component
{
public $title = 'Livewire Counter Component';
public $count = 1;
public function increment()
{
$this->count++;
}
public function decrement()
{
$this->count--;
}
public function render()
{
return view('livewire.counter');
}
}
Here is my app layout:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
{{ $slot }}
</body>
</html>
And, here's where I passed the $title variable to the $title $slot:
<x-slot:title>{{ $title }}</x-slot>
<div class="mx-auto max-w-xl">
<h1 class="font-bold text-5xl text-center">{{ $count }}</h1>
<button class="bg-gray-300 p-2 border border-gray-900 hover:bg-gray-400" wire:click="increment">+</button>
<button class="bg-gray-300 p-2 border border-gray-900 hover:bg-gray-400" wire:click="decrement">-</button>
</div>
Hope that helps!
@cblack267 Thank you very much, you are live saver, turns out just to add x-slot in there.
Please or to participate in this conversation.