'Error 500 while trying to upload an image using FilePond and Laravel Spatie

I'm trying to create items that have a picture/avatar using a form and insert them into my database, so I decided to use Laravel Spatie with the MediaCollection, but as soon as i implemented the library, I'm getting an error 500 when I submit my form.... any idea why? And how am I supposed to create my database fields so when I create a new item with a picture I submit, the picture is submitted in a "Picture" datatable and in my "item" datatable I have the foreign key "picture_id" referencing to the picture in the Picture datatable.

Item.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Item extends Model implements HasMedia
{
    use HasFactory;
    use InteractsWithMedia;


    public function inventory_list()
    {
        return $this->belongsTo(InventoryList::class);
    }

    public function work_ticket()
    {
        return $this->belongsToMany(WorkTicket::class);
    }

    public function picture()
    {
        return $this->belongsTo(Picture::class);
    }
}

ItemController.php:

<?php

namespace App\Http\Controllers;

use App\Models\InventoryList;
use App\Models\Item;
use App\Models\Picture;
use App\Models\TemporaryFile;
use Illuminate\Http\Request;

class ItemController extends Controller
{
    public function index()
    {
        $inventory_lists = InventoryList::all();
        $pictures = Picture::all();

        return view('add-item', ['inventory_lists' => $inventory_lists,
            'pictures' => $pictures]);
    }

    public function store(Request $request)
    {
        $item = new Item;

        $item->name = $request->name;
        $item->state = $request->state;
        $item->observations = $request->observations;
        $item->list_id = $request->list_id;
        $item->picture_id = $request->picture_id;

        $temporaryFile = TemporaryFile::where('folder', $request->avatar)->first();
        if($temporaryFile){
            $item->addMedia(storage_path('app/public/avatars/tmp/' . $request->avatar . '/' . $temporaryFile->filename))
                ->toMediaCollection('avatars');
            rmdir('app/public/avatars/tmp/' . $request->avatar);
            $temporaryFile->delete();
        }

        $item->save();

        return redirect('add-item')->with('status', 'Item Form Data Has Been inserted');
    }
}

add-item.blade.php:

<!DOCTYPE html>
<html>
<head>
    <title>Créer un nouvel item</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
    @if(session('status'))
        <div class="alert alert-success">
            {{ session('status') }}
        </div>
    @endif
    <div class="card">
        <div class="card-header text-center font-weight-bold">
            Ajouter un nouvel item
        </div>
        <div class="card-body">
            <form name="add-blog-post-form" id="add-blog-post-form" method="post" action="{{url('store-item')}}">
                @csrf
                <div class="form-group">
                    <label for="name">Nom</label>
                    <input type="text" id="name" name="name" class="form-control" required="">
                </div>
                <div class="form-group">
                    <label for="state">État</label>
                    <input type="text" id="state" name="state" class="form-control" required="">
                </div>
                <div class="form-group">
                    <label for="observations">Observations</label>
                    <textarea name="observations" class="form-control" required=""></textarea>
                </div>
                <div class="form-group">
                    Liste d'inventaire
                    <select name="list_id" class="form-control select2-multiple">
                        <option value=""></option>
                        @foreach($inventory_lists as $inventory_list)
                            <option value="{{$inventory_list->id}}">
                                {{$inventory_list->name}}
                            </option>
                        @endforeach
                    </select>
                </div>
                <div>
                    <label for="avatar">Photo</label>
                    <input type="file" name="avatar" id="avatar">
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div>
    </div>
    @section('scripts')
        <script>
            const inputElement = document.querySelector('input[id="avatar"]');
            const pond = FilePond.create( inputElement );
            FilePond.setOptions({
                server: {
                    url: '/upload',
                    headers: {
                        'X-CSRF-TOKEN': '{{ csrf_token() }}'
                    }
                }

            });
        </script>
    @endsection
</div>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
@yield('scripts')
</body>
</html>

UploadController.php

<?php

namespace App\Http\Controllers;

use App\Models\TemporaryFile;
use Illuminate\Http\Request;

class UploadController extends Controller
{
    public function store(Request $request)
    {
        if ($request->hasFile('avatar')) {
            $file = $request->file('avatar');
            $filename = $file->getClientOriginalName();
            $folder = uniqid() . '-' .now()->timestamp;
            $file->storeAs('avatars/tmp/' . $folder, $filename);

            TemporaryFile::create([
                'folder' => $folder,
                'filename' => $filename
            ]);
            return $folder;
        }

        return '';
    }
}

2022_05_06_063218_create_temporary_files_table.php:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('temporary_files', function (Blueprint $table) {
            $table->id();
            $table->string('folder');
            $table->string('filename');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('temporary_files');
    }
};

Thanks in advance

Edit:

I got this error right before getting my Error 500, then I simply refreshed my page and I never got the following error again, just an error 500.

local.ERROR: Declaration of Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection::jsonSerialize() must be compatible with Illuminate\Support\Collection::jsonSerialize(): array {"exception":"[object] (Symfony\Component\ErrorHandler\Error\FatalError(code: 0): Declaration of Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection::jsonSerialize() must be compatible with Illuminate\Support\Collection::jsonSerialize(): array at /home/vagrant/code/vendor/spatie/laravel-medialibrary/src/MediaCollections/Models/Collections/MediaCollection.php:51) [stacktrace] #0 {main}



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source