Getting value to show up using livewire - laravel

I'm using laravel and livewire and I'm trying to create an edit page. What I'm trying to do is get the value to show up in the textbox.
So for example my edit page has product info that I'm trying to edit, but my product name isn't displaying in the textbox.
Here is my code
My ProductEdit.php
<?php
namespace Modules\Products\Http\Livewire;
use App\Models\Product;
use Livewire\Component;
class ProductsEdit extends Component
{
public $name;
public $product;
public function render()
{
return view('products::livewire.edit-products', [
'name' => $this->product->name
]);
}
public function updateProduct()
{
dd($this->name);
}
}
My edit-products.blade.php
<div class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id="product_name"
type="text"
name="product_name"
value="{{ $product->name }}"
wire:model="name"
>
</div>
<button wire:click="updateProduct" class="bg-green-400 hover:bg-green-300 text-green-800 font-bold py-2 px-4 rounded inline-flex items-center">Save</button>

Related

How to pass Model as parameters to the Wire (Livewire Laravel)

In the button, I can't pass Model product as parameters to the Wire (Livewire Laravel).
I have two function initiateEdit first in model stockin and the other in model product.
in this code only call the function that found in the stockin model but i want the function in the product model.
how to call the function for the specific model ?
<button
class="flex items-center p-2 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-gray-600 border border-transparent rounded-lg active:bg-gray-600 hover:bg-gray-700 focus:outline-none focus:shadow-outline-gray"
wire:click="$emit('initiateEdit', {{ $product['id'] }} )"
title="{{ __('Edit') }}">
<x-heroicon-o-pencil class="w-5 h-5" />
{{ $slot ?? '' }}
</button>
public function initiateEdit($id)
{
dd($id);
$this->selectedModel = $this->model::find($id);
}

Bind Livewire component to parent array

I have the following structure:
A parent component:
class SiteEditComponent extends Component
{
protected $listeners = ['upClicked', 'downClicked', 'childUpdated'];
public $childBlocks = [];
public function render()
{
return view('livewire.site-edit-component', ['childBlocks' => $this->childBlocks]);
}
}
Which renders that way:
<div>
<button wire:click="addBlock" type="button" class=" mb-3 inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Block hinzufügen</button>
#foreach($childBlocks as $key => $childBlockContent)
<livewire:templates.text-block-component wire:model.debounce="childBlocks.key" :block="$childBlockContent" :wire:key="$key">
#endforeach
</div>
And the child component(s):
class TextBlockComponent extends Component
{
public $block;
protected $rules = [
'block.title' => ''
];
public function render()
{
return view('livewire.text-block-component', [
'block' => $this->block
]);
}
Which renders that way (simplified):
<div>
<div class="bg-white shadow sm:rounded-lg mb-3">
<div class="px-4 py-5 sm:p-6">
<div
class=" w-1/3 border border-gray-300 rounded-md px-3 py-2 shadow-sm focus-within:ring-1 focus-within:ring-indigo-600 focus-within:border-indigo-600">
<label for="name" class="block text-xs font-medium text-gray-900">Titel</label>
<input wire:model.debounce="block.title" type="text" name="title" id="name"
class="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 focus:ring-0 sm:text-sm"
placeholder="Blocküberschrift">
</div>
</div>
</div>
</div>
In fact both components represent a Laravel model. A site can have multiple blocks.
What would be the right way to keep track of the child components in the parent component?
I want to implement a save button which should collect all items of $childBlocks, save the Site and attach the childBlocks to it. I tried to model it by using wire:model.debounce="childBlocks.key" but the binding doesn't seem to work.
I wanted to create an associative array in which every block is identified by a randomly generated key which holds the block data.

Laravel livewire dynamic dropdown with lots of relations on a single model

I have a fairly complex issue, I have an animal
model
class Animal extends Model
{
use HasFactory;
protected $fillable = [
"breed_ID",
"name",
"color_ID",
"eyes_color_ID",
"birth_date",
"animal_types_id",
"born_location",
"profile_picture_id",
"gender_ID",
"status",
"image",
"bio",
"lenght",
"weight",
"passport_url",
"chip_number",
"breeder_ID",
];
protected function genders(): BelongsTo
{
return $this->belongsTo(Gender::class);
}
public function borns(): BelongsTo
{
return $this->belongsTo(Born::class);
}
public function eyeColors(): BelongsTo
{
return $this->belongsTo(EyeColor::class);
}
public function colors(): BelongsTo
{
return $this->belongsTo(Color::class);
}
public function breeders(): BelongsTo
{
return $this->belongsTo(Breeder::class);
}
public function weights(): BelongsTo
{
return $this->belongsTo(Weight::class);
}
public function lengths(): BelongsTo
{
return $this->belongsTo(Length::class);
}
public function users(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function animalTypes(): BelongsTo
{
return $this->belongsTo(AnimalType::class);
}
public function images(): HasMany
{
return $this->hasMany(Image::class);
}
}
This animal has a breed, gender, color e.t.c
When a user wants to add a new animal they are presented a form, this form is a full page livewire component.
<main class="add-animal-page">
<section class="relative">
<div class="container px-4 mx-auto">
<div
class="flex flex-col justify-center w-full min-w-0 mb-6 break-words rounded-lg shadow-xl xl:flex-row bg-gray-50">
<form enctype="multipart/form-data" class="flex justify-center" wire:submit.prevent="upload">
<div class="w-full xl:w-4/6">
<div class="flex justify-center px-4 py-5 sm:p-6">
<div class="grid max-w-4xl grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3 lg:col-span-2">
<label for="first_name" class="block text-sm font-medium text-gray-700">Name</label>
<input type="text" name="first_name" id="first_name" autocomplete="given-name"
wire:model.defer="animal.name"
class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div class="col-span-6 sm:col-span-6">
<label for="type" class="block text-sm font-medium text-gray-700">
Type</label>
<select wire:model="animal.breeds_id" name="breed" id="breed"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose a type</option>
#foreach ($types as $type)
<option value={{ $type->id }}>{{ $type->animal_name }}</option>
#endforeach
</select>
</div>
<div class="col-span-6 sm:col-span-6">
<label for="breed" class="block text-sm font-medium text-gray-700">
Breed</label>
<select wire:model="animal.breeds_id" name="breed" id="breed"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose a breed</option>
#foreach ($breeds as $breed)
<option value={{ $breed->id }}>{{ $breed->breed_name }}</option>
#endforeach
</select>
</div>
<div class="col-span-6 sm:col-span-6">
<label for="breed" class="block text-sm font-medium text-gray-700">
Breed</label>
<select wire:model="animal.breeds_id" name="breed" id="breed"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose a breed</option>
#foreach ($breeds as $breed)
<option value={{ $breed->id }}>{{ $breed->breed_name }}</option>
#endforeach
</select>
</div>
<div class="col-span-6 sm:col-span-6">
<label for="gender" class="block text-sm font-medium text-gray-700">
Gender</label>
<select wire:model="animal.genders_id" name="gender" id="gender"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose a gender</option>
#foreach ($genders as $gender)
<option value={{ $gender->id }}>{{ $gender->type }}</option>
#endforeach
</select>
</div>
<div class="col-span-6 sm:col-span-6">
<label for="eye_color" class="block text-sm font-medium text-gray-700">
Eye color</label>
<select wire:model="animal.eye_color_id" name="eye_color" id="eye_color"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose an eye color</option>
#foreach ($eyeColors as $eyeColor)
<option value={{ $eyeColor->id }}>{{ $eyeColor->name }}</option>
#endforeach
</select>
</div>
<div class="col-span-6 sm:col-span-6">
<label for="Breeder" class="block text-sm font-medium text-gray-700">
Breeder</label>
<select wire:model="animal.breeders_id" name="Breeder" id="Breeder"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose a breeder</option>
#foreach ($breeders as $breeder)
<option value={{ $breeder->id }}>{{ $breeder->name }}</option>
#endforeach
</select>
</div>
<div class="col-span-6 sm:col-span-6">
<label for="passport" class="block text-sm font-medium text-gray-700">
Passport URL</label>
<input type="text" wire:model.defer="animal.passport_url" name="passport"
id="passport" autocomplete="text"
class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div class="col-span-6 sm:col-span-6">
<label for="chip_number" class="block text-sm font-medium text-gray-700">
Chip number</label>
<input type="text" wire:model.defer="animal.chip_number" name="chip_number"
id="chip_number" autocomplete="chip_number"
class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</div>
<div class="col-span-6">
<label for="bio" class="block text-sm font-medium text-gray-700">
Bio
</label>
<div class="mt-1">
<textarea wire:model.defer="animal.bio" id="bio" name="bio" rows="3"
class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
</textarea>
</div>
</div>
</div>
</div>
<div class="max-w-md mx-auto overflow-hidden rounded-lg md:max-w-xl">
<div class="md:flex">
<div class="w-full p-3 ">
<div
class="relative flex items-center justify-center h-48 bg-gray-100 border-2 border-dotted rounded-lg border-primary-light">
<div class="absolute">
<div class="flex flex-col items-center"><i
class="fa fa-folder-open fa-4x text-primary"></i> <span
class="block font-normal text-gray-400">Upload your image
here</span>
</div>
</div>
<input wire:model.defer="image" type="file"
class="w-full h-full opacity-0 cursor-pointer">
</div>
</div>
</div>
</div>
</div>
<div class="absolute bottom-0 right-0 px-6 py-3 mx-4 my-6 text-right bg-gray-50 sm:px-6">
<button type="submit"
class="inline-flex justify-center px-4 py-2 text-sm font-medium text-white border border-transparent rounded-md shadow-sm bg-primary hover:bg-primary-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Save
</button>
</div>
</form>
</div>
</div>
</section>
</main>
The form is populated via this livewire class.
class AddAnimal extends Component
{
use WithFileUploads;
public User $user;
public Animal $animal;
public Collection $genders;
public Collection $eyeColors;
public Collection $breeds;
public Collection $colors;
public Collection $breeders;
public Collection $types;
public $image;
protected array $rules = [
'animal.name' => 'required|min:2',
'animal.eye_color_id' => 'nullable',
'animal.bio' => 'nullable',
'animal.breeds_id' => 'nullable',
'animal.genders_id' => 'nullable',
'animal.breeders_id' => 'nullable',
'animal.chip_number' => 'nullable',
'animal.passport_url' => 'nullable',
'image' => 'nullable',
];
public function mount(User $user)
{
$this->user = $user;
$this->animal = new Animal();
$this->genders = Gender::all();
$this->eyeColors = EyeColor::all();
$this->breeds = Breed::all();
$this->colors = Color::all();
$this->breeders = Breeder::all();
$this->types = AnimalType::all();
}
public function render()
{
return view('livewire.add-animal')
->layout('components.layouts.dashboard', ['title' => 'Add-animal'])
->with(['user' => $this->user, 'genders' => $this->genders, 'eyeColors' => $this->eyeColors, 'breeds' => $this->breeds, 'colors' => $this->colors, 'breeders' => $this->breeders, 'types' => $this->types]);
}
How can I make it so that my dropdowns become dynamic? e.g if a user selects dog as animal type, in the breed dropdown only relevant dog breeds should be shown, and not cats or horses. I tried using some of the online available tutorials to get me started, but could not figure it out with all the relationships going on in my models.
Since the Breed Model has an animal_type id, we can use Livewire's updated hook to check for changes on the animal type and render only breeds related to the animal type.
so in the livewire component,
class AddAnimal extends Component
{
public User $user;
public Animal $animal;
public Collection $genders;
public Collection $eyeColors;
// public Collection $breeds; we will use a computed property
public Collection $colors;
public Collection $breeders;
public Collection $types;
public $image;
// newly added variable to keep track of animal type changed
public $filters = [
'animal_type_id' => ''
];
protected array $rules = [
'animal.name' => 'required|min:2',
'animal.eye_color_id' => 'nullable',
'animal.bio' => 'nullable',
'animal.breeds_id' => 'nullable',
'animal.genders_id' => 'nullable',
'animal.breeders_id' => 'nullable',
'animal.chip_number' => 'nullable',
'animal.passport_url' => 'nullable',
'image' => 'nullable',
'animal.animal_type_id' => '', // make sure you have the rule can be left empty if its not required
];
public function mount(User $user)
{
$this->user = $user;
$this->animal = new Animal();
$this->genders = Gender::all();
$this->eyeColors = EyeColor::all();
$this->colors = Color::all();
$this->breeders = Breeder::all();
$this->types = AnimalType::all();
}
public function updatedAnimalAnimalTypeId($value)
{
$this->filters['animal_type_id'] = $value;
}
public function getBreedsProperty()
{
return Breed::when($this->filters['animal_type_id'], function($query, $animal_type_id){
return $query->where('animal_type_id', $animal_type_id);
})->get();
}
public function render()
{
return view('livewire.add-animal')
->layout('components.layouts.dashboard', ['title' => 'Add-animal'])
->with(['user' => $this->user, 'genders' => $this->genders, 'eyeColors' => $this->eyeColors, 'breeds' => $this->breeds, 'colors' => $this->colors, 'breeders' => $this->breeders, 'types' => $this->types]);
}
}
Note that I have used computed property to get the breeds.
I also have made use of when clause to avoid the null check.
so in the blade file, we just have to wire:model the animal_type_id.
....
<div class="col-span-6 sm:col-span-6">
<label for="type" class="block text-sm font-medium text-gray-700">
Type</label>
<select wire:model="animal.animal_type_id" name="animal_type_id" id="animal_type_id"
class="block w-full px-3 py-2 mt-1 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<option value="">Choose a type</option>
#foreach ($types as $type)
<option value={{ $type->id }}>{{ $type->animal_name }}</option>
#endforeach
</select>
</div>
....
Now the breeds will be rendered based on the animal type selected.
I have assumed animal_type_id is the correct column name in Animal model. if its not, please change the column name respectively.

Laravel Livewire sync($request->input)

public function modelData()
{
$user = User::create([
'name' => $this->name,
'npm' => $this->npm,
'email' => $this->email,
'jurusan' => $this->jurusan,
'fakultas' => $this->fakultas,
'password' => Hash::make($this->password),
]);
$user->roles()->sync($this->input('roles', []));
}
this is my code. please someone help me how to use request -> input in livewire
class Usermanajemen extends Component
{
public $role = [];
public $users;
public $name;
public $npm;
public $email;
public $password;
public $jurusan;
public $fakultas;
use WithPagination;
public $modalFormVisible = false;
public $modelid;
public function render()
{
$this->users = User::orderBy('created_at', 'DESC')->get();
$roles = Role::pluck('title', 'id');
return view('livewire.usermanajemen', compact('roles'));
}
public function create()
{
$this->validate();
User::create($this->modelData());
$this->modalFormVisible = false;
$this->reset();
}
public function closeModal()
{
$this->modalFormVisible = false;
}
public function createShowModal()
{
$this->resetValidation();
$this->reset();
$this->modalFormVisible = true;
}
public function mount()
{
$this->resetPage();
}
/**
* The update function.
*
* #return void
*/
public function rules()
{
return [
'name' => ['required', 'string', 'max:255'],
'npm' => ['required', 'numeric', Rule::unique('users', 'npm')->ignore($this->modelid)],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'min:6'],
'jurusan' => 'required',
'fakultas' => 'required',
];
}
/**
* The data for the model mapped
* in this component.
*
* #return void
*/
public function modelData()
{
$user = User::create([
'name' => $this->name,
'npm' => $this->npm,
'email' => $this->email,
'jurusan' => $this->jurusan,
'fakultas' => $this->fakultas,
'password' => Hash::make($this->password),
]);
$user->roles()->sync($this->role);
}
}
this is my livewire usermanajemen i change my role in create and add role=[]in public
<form>
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="">
<div class="mb-4">
<label for="name" class="block text-gray-700 text-sm font-bold mb-2">Nama:</label>
<input type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="name" wire:model="name">
#error('name') <span class="text-red-500">{{ $message }}</span>#enderror
</div>
<div class="mb-4">
<label for="npm" class="block text-gray-700 text-sm font-bold mb-2">Npm:</label>
<input type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="npm" wire:model="npm">
#error('npm') <span class="text-red-500">{{ $message }}</span>#enderror
</div>
<div class="mb-4">
<label for="email" class="block text-gray-700 text-sm font-bold mb-2">Email:</label>
<input type="email" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="email" wire:model="email">
#error('email') <span class="text-red-500">{{ $message }}</span>#enderror
</div>
<div class="mb-4">
<label for="password" class="block text-gray-700 text-sm font-bold mb-2">Password:</label>
<input type="password" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="password" wire:model="password">
#error('password') <span class="text-red-500">{{ $message }}</span>#enderror
</div>
<div class="mb-4">
<label for="jurusan" class="block text-gray-700 text-sm font-bold mb-2">Jurusan:</label>
<input type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="jurusan" wire:model="jurusan">
#error('jurusan') <span class="text-red-500">{{ $message }}</span>#enderror
</div>
<div class="mb-4">
<label for="fakultas" class="block text-gray-700 text-sm font-bold mb-2">Fakultas:</label>
<input type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="fakultas" wire:model="fakultas">
#error('fakultas') <span class="text-red-500">{{ $message }}</span>#enderror
</div>
<div class="px-4 py-5 bg-white sm:p-6">
<label for="role" class="block font-medium text-sm text-gray-700">Roles</label>
<select wire:model = "role" name="role" id="role" class="form-multiselect block rounded-md shadow-sm mt-1 block w-full" multiple="multiple">
#foreach($roles as $id => $role)
<option value="{{ $id }}"{{ in_array($id, old('roles', [])) ? ' selected' : '' }}>{{ $role }}</option>
#endforeach
</select>
#error('roles')
<p class="text-sm text-red-600">{{ $message }}</p>
#enderror
</div>
</div>
</div>
this is my blade file for create
i change in my livewire and my blade and still error but users added
Why do you want to use request ?
You can add a property like public roles = []; in the class
and bind this property with select/checkbox ie: <select wire:model="role" multiple>
and then you can use sync like this : $user->roles()->sync($this->roles);
PS: I assumed that you already defined many to many relationship

Laravel PATCH works on update but validation in controller fails

I am following along with the Laracast lab, the Tweety feed and all was going good until i hit a wall.
I have a PATCH to update the user profile and it works and updates the record, but the validation doesn't. The form submits if fully complete and the record is fine but if the form validation fails server side in my controller, I get as below:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods: POST.
I have looked at the FAQ section here and scoured the net already asked and tried several steps to sort this. I have tried:
Using $user->username in my edit file template and controller.
Changing the route from PATCH TO PUT (and also POST, simply using store)
Checking the User model and ensuring I am using 'getRouteKeyName' working correctly, it is.
Checking if there is a conflict in the route, there is none and the order/VERB is fine.
Can anyone please help? Below is my code.
Routes as below:
// Snippet for seeing all the database queries.
//DB::listen(function($query){var_dump($query->sql, $query->bindings);});
use Illuminate\Support\Facades\Route;
// Home view, no sign-in required.
Route::get('/', function () {
return view('welcome');
});
// These routes require and use auth middleware.
Route::middleware('auth')->group(function(){
// TWeets main page.
Route::get('/tweets/', 'TweetsController#index')->name('home');
// Store a new tweet
Route::post('/tweets/', 'TweetsController#store');
// Profile area, view and update
// Use the 'name' attribute in route/model binding instead of the primary key = user:name
Route::get('/profile/{user:username}/', 'ProfileController#show')->name('profile');
// Show form to edit the profile
Route::post('/profile/{user:username}/edit','ProfileController#edit')->name('edit_profile');
//->middleware('can:edit,user'); // Don't forget the wildcard.
// Finally, update the users profile information.
Route::patch('/profile/{user:username}','ProfileController#update')->name('update_profile');
// Handles the follow/unfollow on a toggle method.
Route::post('/profile/{user:username}/follow/','FollowsController#store');
// Logs you out & directs to the homepage.
Route::get('/logout', '\App\Http\Controllers\Auth\LoginController#logout');
});
Auth::routes();
Controller as below:
/**
* Update the users profile after validation
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(User $user)
{
$validated = request()->validate([
'name'=>'required',
'username'=>'required',
'password'=>'required',
'password_confirmation'=>'required',
]);
$user->update($validated);
// Redirect to the tweets page which is called 'home'.
return redirect(route('profile', $user->username));
}
Template:
<x-app>
<form class="w-full" method="POST" action="{{route('update_profile',$user)}}">
#method('PATCH')
#csrf
<h2 class="text-xl mb-2 py-4 font-bold">Edit profile for {{$user->username}}</h2>
<p class="text-sm mb-5 mt-0">Below you an update your profile details.</p>
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full px-3 mb-6 md:mb-0">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-name">Name</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white" id="name" type="text" placeholder="Mike Smith.." name="name" value="{{$user->name}}"/>
</div>
#error('name')
<p>{{$message}}</p>
#enderror
<div class="w-full px-3 mb-6 md:mb-0">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-username">Username</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white" id="grid-username" type="text" placeholder="MikeSmith1..." name="username" value="{{$user->username}}"/>
</div>
#error('username')
<p>{{$message}}</p>
#enderror
<div class="w-full px-3 mb-6 md:mb-0">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-username">Email</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white" id="grid-username" type="email" placeholder="MikeSmith#yahoo.com..." name="email" value="{{$user->email}}"/>
</div>
#error('email')
<p>{{$message}}</p>
#enderror
<div class="w-full px-3">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-password">Password</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-password" type="password" name="password"/>
<p class="mb-3 text-red-600 text-xs italic">Make it as long and as crazy as you'd like</p>
</div>
<div class="w-full px-3"> {{-- This HAS to be called "password_confirmation" --}}
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-password">Password Confirmation</label>
<input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-password_confirmation" type="password" name="password_confirmation"/>
</div>
<button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 ml-2 mt-4 px-4 rounded">
Update details
</button>
</div>
</form>
</x-app>
Model:User
/**
* Laravel <=6 - use this method, after v6, you can do this on the route itself.
* Using this so we can use a user name in the route, instead of the ID Laravel normally uses for route/model binding. Now you can use /profile/mikethornley
* This will still enable route/model binding to work and still find the user
* #return [type] [description]
*/
public function getRouteKeyName()
{
return 'username';
}
This is the problem:
// Use the 'name' attribute in route/model binding instead of the primary key = user:name
Route::get('/profile/{user:username}/', 'ProfileController#show')->name('profile');
// Finally, update the users profile information.
Route::patch('/profile/{user:username}','ProfileController#update')->name('update_profile');
Your routes are clashing... that post ends up in the show() method and that's why you get the error.
You need to make some change in that post route if you want to have parameters. For example
Route::patch('/profile-update/{user:username}','ProfileController#update')->name('update_profile');

Resources