Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

257
Views
enum class in ternary expression

Enums were introduced to PHP very recently. I'm trying them out in a laravel project. I've got my enum class here:

namespace App\Enums;

enum AlertType
{
    case SUCCESS;
    case ERROR;
}

I'm trying to create an alert class that will take the enum in the constructor to set the severity of the alert, which will decide what colour it is rendered as to the user. Here is that class:

<?php

namespace App\View\Components;

use App\Enums\AlertType;
use Illuminate\View\Component;

class Alert extends Component
{
    public string $contextClass;

    public function __construct(public string $message, AlertType $alertType = AlertType::SUCCESS)
    {
        $this->setContextClassFromAlertType($alertType);
    }

    public function setContextClassFromAlertType(AlertType $alertType)
    {
        $this->contextClass = ($alertType === AlertType::SUCCESS ? 'success' : 'error');
    }

    public function getClassListFromType()
    {
        return [
            'border-' . $this->contextClass,
            'text-' . $this->contextClass
        ];
    }

    public function render()
    {
        return view('components.alert', [
            'class' => implode(' ', $this->getClassListFromType())
        ]);
    }
}

This alert will be used in a login form which is built using Laravel Livewire and blade components:

<form class="grid grid-cols-min-auto-1 gap-x-2" id="login" action="/login" method="post">
    <x-alert :message="$errorMessage"/>
    @csrf
    <label for="email" class="mb-2 text-lg text-sans w-min mt-2 font-thin">Email</label>
    <x-basic-input wire:model="email" placeholder="{{ $emailPlaceholder }}"/>
    <label for="password" class="mb-2 text-lg text-sans w-min mt-2 font-thin">Password</label>
    <x-basic-input wire:model="password"/>
</form>

When I come to display the login form I am getting the following error:

Cannot instantiate enum App\Enums\AlertType (View: /resources/views/livewire/forms/login.blade.php)

I think there is something wrong with my enum usage in the Alert component, but I'm not sure where. Can anyone point me in the right direction. I've looked at the rfc for enums but I can't see anything obvious that I'm doing wrong

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

I was able to reproduce this error; in my case the stack trace led back to the barryvdh/laravel-debugbar package, not sure if this is the same for you. I was able to resolve it by changing the enum to a backed enum.

I'd recommend making this change regardless, as I expect in a lot of cases strings will be easier to work with than enum instances. (Though TBH this looks like trying to use a new feature just because it's there, not because it makes sense.)

namespace App\Enums;

enum AlertType: string
{
    case SUCCESS = 'success';
    case ERROR = 'error';
    case INFO = 'info';
}

In a backed enum, each item has a string representation that can be accessed using the value property, which we do in the constructor:

<?php

namespace App\View\Components;

use App\Enums\AlertType;
use Illuminate\View\Component;

class Alert extends Component
{
    public string $contextClass;

    public function __construct(
        public string $message,
        AlertType $alertType = AlertType::SUCCESS,
    )
    {
        $this->contextClass = $alertType->value;
    }

    public function getClassListFromType()
    {
        return [
            'border-' . $this->contextClass,
            'text-' . $this->contextClass
        ];
    }

    public function render()
    {
        return view('components.alert', [
            'class' => implode(' ', $this->getClassListFromType())
        ]);
    }
}

You're now able to use the from() or tryFrom() methods which can add flexibility with alert types saved in a variable. For example:

<x-alert :message="$errorMessage" :type="App\Enums\AlertType::from($errorType)"/>
over 4 years ago · Santiago Trujillo Report

0

I think the problem here is due to dependency injection. In the constructor I'm typehinting an enum, so the Laravel container is trying to create an instance of that class to pass in which doesn't work because enums are instantiable.

If I update the container to manually resolve the typehinted instance like this:

$this->app->bind(Alert::class, function ($app) {
    return new Alert('this is a message', AlertType::SUCCESS);
});

Then the issue is resolved and it works as expected. I'll need to change the way I'm using enums here as @miken32 suggests to use a backed enum and rely on the strings instead. Otherwise I'd need to override the container injection for every method where I wanted to pass an enum.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!