Fileupload in Single record editing with custom page

im trying to follow this instruction online https://laraveldaily.com/post/filament-edit-only-single-record-custom-page, but the example was only for text input. I try something like fileupload for my case, since the mountng and saving data work around array, i have a problem for fileupload (filepond). instead of saving the filename, it save a weird json (logs on the bottom) and the tmp file are not moved to the storage disk, is there a way to make fileupload in my custom page works like in resource page ? https://pastebin.com/YypB3kbd (the code)
[2025-01-29 18:45:27] local.INFO: EditSchool mount(): School data loaded {"school_id":7527}
[2025-01-29 18:46:09] local.INFO: EditSchool save(): Form data received {"data":{"id":7527,"name":"Drake Mathews","head_master":"Dorothy Munoz","head_master_photo":{"8d3531b5-084c-4110-8b03-f340ef3ae6ac":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/phpuibqjc95utj31VnBah3"}},"accompanying_teacher":"Burris and James Trading","accompanying_teacher_photo":{"c6f21f1e-6036-4054-9041-db098ff6f6e6":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/phphm8m9ivisdlr9w3Tqru"}},"address":"Cum odit ex omnis su","phone_number":"1901-5646-608","email":"[email protected]","contingent_leader":"Trevor Berger","contingent_leader_photo":{"6be73be6-3abf-45d7-a3cd-ea51dc73e836":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/php06duca0965ro3kBNg5R"}},"created_at":"2025-01-29T10:54:31.000000Z","updated_at":"2025-01-29T18:27:34.000000Z","event_id":1}}
[2025-01-29 18:45:27] local.INFO: EditSchool mount(): School data loaded {"school_id":7527}
[2025-01-29 18:46:09] local.INFO: EditSchool save(): Form data received {"data":{"id":7527,"name":"Drake Mathews","head_master":"Dorothy Munoz","head_master_photo":{"8d3531b5-084c-4110-8b03-f340ef3ae6ac":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/phpuibqjc95utj31VnBah3"}},"accompanying_teacher":"Burris and James Trading","accompanying_teacher_photo":{"c6f21f1e-6036-4054-9041-db098ff6f6e6":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/phphm8m9ivisdlr9w3Tqru"}},"address":"Cum odit ex omnis su","phone_number":"1901-5646-608","email":"[email protected]","contingent_leader":"Trevor Berger","contingent_leader_photo":{"6be73be6-3abf-45d7-a3cd-ea51dc73e836":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/php06duca0965ro3kBNg5R"}},"created_at":"2025-01-29T10:54:31.000000Z","updated_at":"2025-01-29T18:27:34.000000Z","event_id":1}}
Pastebin
EditSchool.php - Pastebin.com
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Solution:
Thanks for all the help, i had to manually mutate the file before storing in db, so it will take the actual file path ```php public function save(): void {...
Jump to solution
24 Replies
waterflai
waterflaiOP4w ago
i dont think so, since the save method are taking form to array resulting the filepond instance to be like this
head_master_photo":{"8d3531b5-084c-4110-8b03-f340ef3ae6ac":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/phpuibqjc95utj31VnBah3"}}
head_master_photo":{"8d3531b5-084c-4110-8b03-f340ef3ae6ac":{"Livewire\\Features\\SupportFileUploads\\TemporaryUploadedFile":"/private/var/folders/0_/q6vx8bs94rz2gsmpn015m9x80000gn/T/phpuibqjc95utj31VnBah3"}}
i do tinker around to fix it by manually moving from tmp to storage disk but the solution just creating another problem lets say i do successfully store the file i just upload, next time im trying to update the data without touching the file, its getting back to the weird json stuff again, but this time beause the original image are not exist in tmp right now im looking for best practices or the correct way to fix it, because i can see some plugin having fileuploads in their custom pages, and they still manage to overcome my problem
waterflai
waterflaiOP4w ago
No description
No description
biebthesecond
biebthesecond4w ago
Also, when using the data from your form you should use: $data = $this->form->getState()
waterflai
waterflaiOP4w ago
Its not that either :”
awcodes
awcodes4w ago
Why are you overriding the default saving of the images? The file upload field will always be an array even if it’s just one image. Seems like you’re not compensating that in your save functionality.
waterflai
waterflaiOP4w ago
Well if im not overriding it it will store an array instead of actual file name, that what happens. You can check the log, but instead all of that it only save {uuid : {}} Im kinda lost and cant find any example online
awcodes
awcodes4w ago
That’s kind of my point. If you source dive the component it’s handling the array vs not array on saving. But you’re overriding that and not handling it.
waterflai
waterflaiOP4w ago
The sql screenshot happen when im overriding it, if im not doing it it stores empty value of the uuid like uuid : {} But first i wanna appreciate the help <3 I will take a look again of it <3
awcodes
awcodes4w ago
Then something else in your app is changing it. But default unless the field is set to multiple, the only thing stored in the db for the file upload is the storage path for the image. If it’s multiple, then it will be an array of the storage paths. The uuids aren’t stored by default since they are dynamic on hydration of the field. Could be a possible mismatch of casts on the model?.
waterflai
waterflaiOP4w ago
Yesss, i expect this as well Since i happen to have fileupload in one of my resources (same model) and it works out of the box with local disk and the destination But when i use it on custom page (before im adding code to override the file upload because it wont upload automatically), it stuck on the tmp folder and when im saving it, and the db value for the image is a json with uuid as a key and empty object
awcodes
awcodes4w ago
Make sure you are calling form->fill() in the mount method of the custom page. Kinda of making some guesses here without the full code. Don’t hate me.
waterflai
waterflaiOP4w ago
I have the full code in pastebin there, you may take a look at it, i’ll remove the overriding part and make it default like the tutorial I do the form fill as in the code i provide I’ll get the model as well <3 Be right back
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class School extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name', // Name of the school
'head_master', // Name of the head master
'head_master_photo', // URL or path to the head master's photo
'accompanying_teacher', // Name of the accompanying teacher/coach
'accompanying_teacher_photo', // URL or path to the accompanying teacher's photo
'address', // Address of the school
'phone_number', // Phone number of the school
'email', // Email of the school
'contingent_leader', // Name of the contingent leader
'contingent_leader_photo', // URL or path to the contingent leader's photo
'event_id', // Foreign key to the events table
];

/**
* Get the event associated with the school.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function event(): BelongsTo
{
return $this->belongsTo(Event::class);
}

/**
* Get the users associated with the school.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users(): HasMany
{
return $this->hasMany(User::class);
}

/**
* Get the teams associated with the school.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function teams(): HasMany
{
return $this->hasMany(Team::class, 'user_id');
}
}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class School extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name', // Name of the school
'head_master', // Name of the head master
'head_master_photo', // URL or path to the head master's photo
'accompanying_teacher', // Name of the accompanying teacher/coach
'accompanying_teacher_photo', // URL or path to the accompanying teacher's photo
'address', // Address of the school
'phone_number', // Phone number of the school
'email', // Email of the school
'contingent_leader', // Name of the contingent leader
'contingent_leader_photo', // URL or path to the contingent leader's photo
'event_id', // Foreign key to the events table
];

/**
* Get the event associated with the school.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function event(): BelongsTo
{
return $this->belongsTo(Event::class);
}

/**
* Get the users associated with the school.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users(): HasMany
{
return $this->hasMany(User::class);
}

/**
* Get the teams associated with the school.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function teams(): HasMany
{
return $this->hasMany(Team::class, 'user_id');
}
}
waterflai
waterflaiOP4w ago
A Free Database Designer for Developers and Analysts
Quick and simple free tool to help you draw your database relationship diagrams and flow quickly using just keyboard
waterflai
waterflaiOP4w ago
i did not override the fileupload this time https://pastebin.com/BcQBKm2h
Pastebin
EditSchool.php (default) - Pastebin.com
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
No description
LeandroFerreira
I didn't follow the messages but I think the issue is that you are not using $this->form->getState() to get the form data
LeandroFerreira
you can validate and get the form's data using $this->form->getState(). It's important that you use this method instead of accessing the $this->data property directly https://filamentphp.com/docs/3.x/forms/adding-a-form-to-a-livewire-component/#adding-the-form
waterflai
waterflaiOP4w ago
I see ! thank you for it, but when i try it, now the file is finally moved to the disk and destination automatically
public function save(): void
{
$this->validate();

$data = $this->form->getState();

// ✅ Manually update the record
$this->school->update($this->data);

Notification::make()
->success()
->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'))
->send();
}
public function save(): void
{
$this->validate();

$data = $this->form->getState();

// ✅ Manually update the record
$this->school->update($this->data);

Notification::make()
->success()
->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'))
->send();
}
but somehow the db value for the file are still json, but this time it has value of correct path
{"438561d2-e57f-46c5-afcd-bd53b448dd3d":"schools\/head_masters\/01JJTM1JAZ976YVZPMRS8F5V5J.jpg"}
{"438561d2-e57f-46c5-afcd-bd53b448dd3d":"schools\/head_masters\/01JJTM1JAZ976YVZPMRS8F5V5J.jpg"}
No description
LeandroFerreira
Remove this->validate
waterflai
waterflaiOP4w ago
Oki, i just did right now and check its still the same the data still stored like this
{"438561d2-e57f-46c5-afcd-bd53b448dd3d":"schools\/head_masters\/01JJTM1JAZ976YVZPMRS8F5V5J.jpg"}
{"438561d2-e57f-46c5-afcd-bd53b448dd3d":"schools\/head_masters\/01JJTM1JAZ976YVZPMRS8F5V5J.jpg"}
waterflai
waterflaiOP4w ago
No description
waterflai
waterflaiOP4w ago
No description
Solution
waterflai
waterflai4w ago
Thanks for all the help, i had to manually mutate the file before storing in db, so it will take the actual file path
public function save(): void
{
// Get the form data
$data = $this->form->getState();

// Process file upload fields
foreach (['head_master_photo', 'accompanying_teacher_photo', 'contingent_leader_photo'] as $field) {
if (isset($data[$field]) && is_array($data[$field])) {
// Extract the file path from the nested structure
$filePath = array_values($data[$field])[0];
$data[$field] = $filePath; // Update the data with the file path only
}
}

// Update the school record with the processed data
$this->school->update($data);

Notification::make()
->success()
->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'))
->send();
}
public function save(): void
{
// Get the form data
$data = $this->form->getState();

// Process file upload fields
foreach (['head_master_photo', 'accompanying_teacher_photo', 'contingent_leader_photo'] as $field) {
if (isset($data[$field]) && is_array($data[$field])) {
// Extract the file path from the nested structure
$filePath = array_values($data[$field])[0];
$data[$field] = $filePath; // Update the data with the file path only
}
}

// Update the school record with the processed data
$this->school->update($data);

Notification::make()
->success()
->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'))
->send();
}

Did you find this page helpful?