Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Enums with Inertia - Vue Js

I was wondering if there was a neat way through the inertia middleware to pass through php enums into vue js.

Basically to be able to re-use labels, values in vue from one source and that being from php (laravel).

Not sure if anyone has thought about this but would be interested to hear.

Thanks

like image 202
Jack Kitley Avatar asked Oct 18 '25 20:10

Jack Kitley


1 Answers

Did you ever come up with a solution for this? Otherwise, you can define a PHP 8.1 Enum with a trait that includes a method for generating a select options array, e.g.:

// app\Enums\Status.php

namespace App\Enums;

use App\Enums\Concerns\HasOptions;

enum Status: int
{
    use HasOptions;

    case DRAFTED = 1;
    case SUBMITTED = 2;
    case APPROVED = 3;

    public function displayName(): string
    {
        return match ($this) {
            self::DRAFTED => 'drafted',
            self::SUBMITTED => 'submitted',
            self::APPROVED => 'approved'
        };
    }
}

// app\Enums\Concerns\HasOptions.php

namespace App\Enums\Concerns;

trait HasOptions
{
    public static function options(): array
    {
        return collect(self::cases())
            ->map(function ($enum) {
                return [
                    'name' => $enum->displayName(),
                    'value' => $enum->value,
                ];
            })->toArray();
    }

    abstract public function displayName(): string;
}

In the Inertia middleware, you can pass this select options in the share method, e.g.:

// app/Http/Middleware/HandleInertiaRequests.php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Inertia\Middleware;
use Tightenco\Ziggy\Ziggy;
use App\Enums\Status;

class HandleInertiaRequests extends Middleware
{
    ...
    
    public function share(Request $request): array
    {
        return array_merge(parent::share($request), [
            ...
            statusOptions => Status::options(),
        ]);
    }
}

And retrieve the select array using the usePage composable, e.g.:

// resources/js/Pages/MyPage.vue

import { usePage } from @inertiajs/vue3;

const statusOptions = usePage().props.statusOptions;

Or if you only wanted to pass the select options array to a specific page instead of globally, you can just pass it as a prop, e.g.:

// app/Http/Controllers/MyPageController.php

namespace App\Http\Controllers;

use App\Enums\Status;

class MyPageController extends Controller 
{
    public function index()
    {
        return Inertia::render('MyPage', [
            'statusOptions' => Status::options()
        ]);
    }
}

// resources/js/Pages/MyPage.vue

const { statusOptions } = defineProps(['statusOptions']);

like image 104
duyn Avatar answered Oct 21 '25 11:10

duyn