You need to show validation errors
profile updating not working
trying to update users profile so i created this livewire component, when i click the update button nothing is happening im not getting errors also
please state my mistake
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
class ProfileUpdate extends Component
{
public $data, $name, $email, $creator_name, $creator_bio;
public function edit($id)
{
$record = User::findOrFail($id);
$this->selected_id = $id;
$this->name = $record->name;
$this->creator_name = $record->creator_name;
$this->creator_bio = $record->creator_bio;
$this->email = $record->email;
}
public function update()
{
$this->validate([
'name' => 'required|min:5',
'email' => 'required|email:rfc,dns'
]);
if ($this->id) {
$record = User::find($this->id);
$record->update([
'name' => $this->name,
'creator_name' => $this->creator_name,
'crearor_bio' => $this->creator_bio,
'email' => $this->email
]);
}
}
public function render()
{
return view('livewire.profile-update');
}
}
livewire view
<form wire:submit.prevent="update" action="#" class="px-4 py-6 space-y-4">
<div>
<input type="hidden" wire:model="">
<div class="form-group">
<label for="exampleInputPassword1">Enter Name</label>
<input type="text" wire:model="name" class="form-control input-sm" placeholder="Name">
</div>
<div class="form-group">
<label>Enter Email</label>
<input type="email" class="form-control input-sm" placeholder="Enter email" wire:model="email">
</div>
<button class="btn btn-primary">Update</button>
</div>
</form>
@Sinnbeck after adding the validation errors I tried changing the email but what I'm getting
the email must be a valid address
@Kikismedia so key in a valid email address
@Snapey done that's still getting same error
@Kikismedia since you check dns it must be a real domain not just the right pattern
@Snapey i have refactor my code still the update is not submitting, and im not getting error
public $users, $name, $email, $user_id, $creator_name, $creator_bio;
public $updateMode = false;
private function resetInputFields(){
$this->name = '';
$this->email = '';
$this->creator_name = '';
$this->creator_bio = '';
}
public function edit($id)
{
$this->updateMode = true;
$user = User::where('id',$id)->first();
$this->user_id = $id;
$this->name = $user->name;
$this->email = $user->email;
$this->creator_name = $user->creator_name;
$this->creator_bio = $user->creator_bio;
}
public function cancel()
{
$this->updateMode = false;
$this->resetInputFields();
}
public function update()
{
$validatedDate = $this->validate([
'name' => 'required',
'email' => 'required|email',
]);
if ($this->user_id) {
$user = User::find($this->user_id);
$user->update([
'name' => $this->name,
'email' => $this->email,
]);
$this->updateMode = false;
session()->flash('message', 'Users Updated Successfully.');
$this->resetInputFields();
}
}
// public function delete($id)
// {
// if($id){
// User::where('id',$id)->delete();
// session()->flash('message', 'Users Deleted Successfully.');
// }
// }
public function render()
{
return view('livewire.profile-update');
}
here is my form
<div>
<form>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Name</label>
<input type="text" class="form-control" wire:model="name" id="exampleFormControlInput1" placeholder="Enter Name">
@error('name') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Creator Name</label>
<input type="text" class="form-control" wire:model="creator_name" id="exampleFormControlInput1" placeholder="Enter Name">
@error('creator_name') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Creator Bio</label>
<input type="text" class="form-control" wire:model="creator_bio" id="exampleFormControlInput1" placeholder="Enter Name">
@error('creator_bio') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<label for="exampleFormControlInput2">Email address</label>
<input type="email" class="form-control" wire:model="email" id="exampleFormControlInput2" placeholder="Enter Email">
@error('email') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<button wire:click.prevent="update()" class="btn btn-dark">Update</button>
<button wire:click.prevent="cancel()" class="btn btn-danger">Cancel</button>
</form>
</div>
@Kikismedia are those fields $fillable
@Snapey yes
@kikismedia $this->id OR $this->selected_id?
@webrobert $this->id
does the id go here??
<input type="hidden" wire:model="">
I'm missing where you set the id.
@webrobert yes
Try adding a dd inside the if statement to check if it actually hit
public function update()
{
$validatedDate = $this->validate([
'name' => 'required',
'email' => 'required|email',
]);
if ($this->user_id) {
dd('There is a user id');
$user = User::find($this->user_id);
$user->update([
'name' => $this->name,
'email' => $this->email,
]);
$this->updateMode = false;
session()->flash('message', 'Users Updated Successfully.');
$this->resetInputFields();
} else {
dd('There is NOT a user id');
}
}
@Sinnbeck ok will try that
@Sinnbeck I'm getting there is no user_id
@Kikismedia Are you sure that thed edit() method is called?
Did you mean to use the mount method? https://laravel-livewire.com/docs/2.x/rendering-components
@Sinnbeck I didn't use the mount method
@Kikismedia I know.. I asked if you meant to.. How is livewire hitting the edit method?
@Sinnbeck I'm using the User profile controller to call the edit method
@snapey @webrobert @sinnbeck I tried passing
public $user_id = 1;
it worked , please how can I get users I'd , when they click thr edit method
Something is clearly a miss. but since we're still here. save some lines..
public User $user;
public $updateMode = false;
protected $rules = [
'user.name' => 'required',
'user.email' => 'required|email',
// must add addition fields here
];
public function edit(User $user)
{
$this->user = $user;
$this->updateMode = true;
}
public function cancel()
{
$this->updateMode = false;
$this->reset();
}
public function save()
{
$this->validate();
$this->user->save();
$this->updateMode = false;
session()->flash('message', 'Users Updated Successfully.'); // this works?
$this->reset();
}
public function render()
{
return view('livewire.profile-update');
}
For Binding Directly To Model Properties
Note: For this to work, you have a validation entry in the
$rulesproperty for any model attributes you want to bind to. Otherwise, an error will be thrown.
Then in the form just prefix your wire:model inputs with user...
...
<input wire:model="user.email" ... >
if all this ☝🏼 doesn't work readily. add a mount method... (also the newest version has a boot method)
public function mount()
{
$this->user = new User();
}
@Kikismedia is the button for selecting the profile to edit in the same component view?
Show the code for the button?
@Snapey no its not
<div class="flex justify-around font-black uppercase">
<div class="px-4 py-2 text-purple-400 border-2 border-purple-400 rounded-md ml-9"><a href="" wire:click="edit({{ $user->id }})" class="">Edit Profile</a></div>
<div class="px-4 py-2 text-purple-400 border-2 border-purple-400 rounded-md mr-9">Manage Movies</div>
</div>
@webrobert error
Typed property App\Http\Livewire\ProfileUpdate::$user must not be accessed before initialization
@Kikismedia yeah, then add the mount method.
Unable to call component method. Public method [update] not found on component: [profile-update]
@Kikismedia why might that be? so you click your update button that is trying to find the update method. but you've replaced that method with a method called save.
@webrobert i dont want users to be able to update there phone number, password and username
the error im getting is requesting for value for phone_number
SQLSTATE[HY000]: General error: 1364 Field 'phone_number' doesn't have a default value (SQL: insert into `users` (`name`, `email`, `username`, `updated_at`, `created_at`) values (theuser, [email protected], probably, 2021-10-06 19:10:25, 2021-10-06 19:10:25))
@webrobert ok here is my profiile-update component blade
<div>
<form>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Name</label>
<input type="text" value="" class="form-control" wire:model="user.name" id="exampleFormControlInput1" placeholder="{{ auth()->user()->name }}">
@error('name') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Creator Bio</label>
<input type="text" class="form-control" wire:model="user.username" id="exampleFormControlInput1" placeholder="Enter Username">
@error('username') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Creator Name</label>
<input type="text" class="form-control" wire:model="creator_name" id="exampleFormControlInput1" placeholder="Enter Name">
@error('creator_name') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<input type="hidden" wire:model="user_id">
<label for="exampleFormControlInput1">Creator Bio</label>
<input type="text" class="form-control" wire:model="creator_bio" id="exampleFormControlInput1" placeholder="Enter Name">
@error('creator_bio') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<div class="form-group">
<label for="exampleFormControlInput2">Email address</label>
<input type="email" class="form-control" wire:model="user.email" id="exampleFormControlInput2" placeholder="Enter Email">
@error('email') <span class="text-danger">{{ $message }}</span>@enderror
</div>
<button wire:click.prevent="update()" class="btn btn-dark">Update</button>
<button wire:click.prevent="cancel()" class="btn btn-danger">Cancel</button>
</form>
</div>
here is m user profile where the edit button is called
<div class="h-screen bg-gray-50">
<div class="flex justify-center">
<div class="">
<div class="flex flex-col items-center justify-center mt-5">
<div class="">
<img class="w-20 h-20 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</div>
<div class="flex my-4">
<h3 class="text-xl font-extrabold">{{ $user->username }}</h3>
<span class="ml-1 text-xl font-extrabold text-purple-400"><i class="fad fa-badge-check"></i></span>
</div>
</div>
<div class="flex justify-around font-black uppercase">
<div class="px-4 py-2 text-purple-400 border-2 border-purple-400 rounded-md ml-9"><a href="" wire:click="edit({{ $user->id }})" class="">Edit Profile</a></div>
<div class="px-4 py-2 text-purple-400 border-2 border-purple-400 rounded-md mr-9">Manage Movies</div>
</div>
<div class="flex items-center justify-center mt-3">
<div class="flex flex-col text-center">
<span class="font-bold">0</span>
<span class="text-sm font-light">Subcribers</span>
</div>
<div class="flex flex-col px-2 mx-3 text-center border-l-2 border-r-2 border-gray-300">
<span class="font-bold">{{ $user->movie->count() }}</span>
<span class="text-sm font-light">Claim Movies</span>
</div>
<div class="flex flex-col text-center">
<span class="font-bold">{{ $user->created_at->diffForHumans() }}</span>
<span class="text-sm font-light">Joined</span>
</div>
</div>
@if ($user->creator)
<div
x-data="{
openTab: 1,
activeClasses: 'border-l border-t border-r rounded-t text-blue-700',
inactiveClasses: 'text-blue-500 hover:text-blue-800'
}"
class="flex flex-col items-center justify-center p-6"
>
<ul class="flex border-b">
<li @click="openTab = 1" :class="{ '-mb-px': openTab === 1 }" class="mr-1 -mb-px">
<a :class="openTab === 1 ? activeClasses : inactiveClasses" class="inline-block px-4 py-2 font-semibold bg-white" href="#">
Claimed Movies
</a>
</li>
<li @click="openTab = 2" :class="{ '-mb-px': openTab === 2 }" class="mr-1">
<a :class="openTab === 2 ? activeClasses : inactiveClasses" class="inline-block px-4 py-2 font-semibold bg-white" href="#">Content</a>
</li>
<li @click="openTab = 3" :class="{ '-mb-px': openTab === 3 }" class="mr-1">
<a :class="openTab === 3 ? activeClasses : inactiveClasses" class="inline-block px-4 py-2 font-semibold bg-white" href="#">Subscribers</a>
</li>
</ul>
<div class="w-full pt-4">
<div x-show="openTab === 1">
<livewire:claimed-movie />
</div>
<div x-show="openTab === 2">
<livewire:profile-post />
</div>
<div x-show="openTab === 3">Tab #3</div>
</div>
</div>
@else
<div class="text-sm text-center">
<div class="flex items-center justify-center mt-3">
<img src="{{ asset('img/ilus/post-bro.png') }}" alt="" class="mt-2 w-60 h-60">
</div>
<h3 class="my-4 text-lg font-semibold">Create a content</h3>
<p class="">Share it with anyone or everyone <br/>
Public content & claimed movies will appear here
</p>
<div class="mt-6">
<a href="" class="px-4 py-2 text-lg text-white uppercase bg-purple-400 rounded-sm">create</a>
</div>
</div>
@endif
</div>
</div>
</div>
@webrobert I'm awaiting your reply
It looks good. When the form loads it has the correct user?
The error is not livewire-related. The database is upset about the phone_number field.
SQLSTATE[HY000]: General error: 1364 Field 'phone_number' doesn't have a default value
@webrobert ok let's me add the phone number value then
@webrobert can I say the edit method isn't getting the user_id ?
sure way to know.... dd() the user there.
public function save()
{
dd( $this->user);
...
You cannot wire:click from outside of the Livewire component. If you need this, then you will need to emit a javascript event and then add a listener to your component
@webrobert so after die and dump i got this
App\Models\User {#345 ▼
#guarded: []
#fillable: array:9 [▼
0 => "name"
1 => "email"
2 => "username"
3 => "password"
4 => "phone_number"
5 => "isVerified"
6 => "creator_name"
7 => "creator_bio"
8 => "avatar"
]
#hidden: array:2 [▶]
#casts: array:1 [▶]
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: false
+wasRecentlyCreated: false
#attributes: array:3 [▶]
#original: []
#changes: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#rememberTokenName: "remember_token"
#accessToken: null
}
@Kikismedia, are you using the livewire component code that I posted? or are you using the code from before?
EDIT: So this component is only being used for the user profile page? Why not just pass the user into the component or use the auth()-user() in the component to begin with?
EDIT AGAIN: Back up the truck.
here is my user profile where the edit button is called.
So you call edit from another component?
@webrobert I'm using your own code
Here is a stripped-down example of a user account page I happen to be working on. I've only removed unnecessary HTML and styles for readability.
normal blade page for account page
...
<livewire:settings.account :user="auth()->user()" />
<hr />
<livewire:settings.notifications :user="auth()->user()" />
...
livewire blade for settings.account
...
<form action="#" wire:submit.prevent="save">
<div>
<input type="text" wire:model="user.username" name="username" id="username" >
@error('user.username') <span>{{ $message }}</span> @enderror
</div>
<div>
<input type="text" wire:model="user.email" name="email" id="email" >
@error('user.email') <span>{{ $message }}</span> @enderror
</div>
<div>
<button type="submit">Save</button>
</div>
</form>
livewire settings.account
<?php
namespace App\Http\Livewire\Settings;
use Livewire\Component;
use App\Models\User;
class Account extends Component
{
public User $user;
protected function rules()
{
return [
'user.username' => ['required', 'unique:users,username,' . $this->user->id],
'user.email' => 'required|email',
];
}
public function save()
{
$this->validate();
$this->user->save();
$this->browserToaster('saved'); // this is a custom macro that calls a browserEvent for toasters.
}
public function render()
{
return view('settings.account');
}
}
@webrobert let me give that's a trial I hope it works
@webrobert where is your edit method
@webrobert thanks for the assist when i clicked on the edit button im getting error
unable to call component method public [edit] not found on component [user-profile]
@Kikismedia 🤷🏼♂️ at this point I practically wrote the thing for you. Study the code and reread everyone's replies. All good info. I think everything is covered here in this thread.
@webrobert thanks I will figure it out
Please or to participate in this conversation.