finchy70's avatar

Component returns Unable to locate a class or view for component [slot] error

I have this component. It is similar is to 3 other components that do a similar job but this component is returning a strange error

Unable to locate a class or view for component [slot]. (View: /var/www/html/resources/views/livewire/risks/create-risk.blade.php)

I must have made a simple mistake that I have become blind to. Here is the component html.

<div>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            Risk Assessments
        </h2>
    </x-slot>

    <div class="space-y-2">
        <div class="hidden px-2 py-1 bg-green-300 border border-green-500 rounded-md font-bold text-green-800
                    bg-yellow-300 border border-yellow-500 rounded-md font-bold text-yellow-800
                    bg-red-300 border border-red-500 rounded-md font-bold text-red-800"></div>
        <div class="max-w-4xl mx-auto flex justify-between">
            <div>
                <x-input.text wire:model="search" placeholder="Search Operations..."></x-input.text>
            </div>

            <x-button.primary wire:click="create" >
                New Risk
            </x-button.primary>

        </div>

        <div class="py-4">
            @foreach($risks as $risk)
                <x-risks.risk-table :risk="$risk"></x-risks.risk-table>
            @endforeach
            <div class="max-w-4xl mx-auto">
                @isset($risks)
                    {{$risks->links()}}
                @endisset
            </div>
        </div>
        <form wire:submit.prevent="save">
            <x-modal.dialog maxWidth="6xl" wire:model.defer="showEditModal">
                <x-slot name="title">{{$modalTitle}}</x-slot>
                <x-slot name="content">
                    <div>
                        <x-input.group for="operation" inline="true" label="Operation" :error="$errors->first('editing.operation')">
                            <x-input.text class="w-full" wire:model="editing.operation" name="operation"></x-input.text>
                        </x-input.group>

                        <x-input.group for="hazard" inline="true" label="Hazard" :error="$errors->first('editing.hazard')">
                            <x-input.text class="w-full" wire:model="editing.hazard" name="hazard"></x-input.text>
                        </x-input.group>

                        <x-input.group for="risk" inline="true" label="Risk" :error="$errors->first('editing.risk')">
                            <x-input.text class="w-full" wire:model="editing.risk" name="risk"></x-input.text>
                        </x-input.group>

                        <x-input.group for="at_risk" inline="true" label="At Risk" :error="$errors->first('editing.at_risk')">
                            <x-input.text class="w-full" wire:model="editing.at_risk" name="at_risk"></x-input.text>
                        </x-input.group>

                        <div class="mt-4">
                            <label class="block font-medium text-sm text-gray-700" for="editing.pre_probability">
                                Pre-Controls Probability
                            </label>
                            <select wire:model="editing.pre_probability" name="editing.pre_probability"
                                    class="mt-2 text-xs text-gray-700 sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400">
                                <option value="0">-- Choose Rating --</option>
                                <option value="1">1 - Low</option>
                                <option value="2">2 - Low / Medium</option>
                                <option value="3">3 - Medium</option>
                                <option value="4">4 - Medium / High</option>
                                <option value="5">5 - High</option>

                            </select>
                            @error('editing.pre_probability')<span class="mt-1 text-red-500 text-sm">{{$message}}</span> @enderror
                        </div>

                        <div class="mt-4">
                            <label class="block font-medium text-xs text-gray-700" for="editing.pre_severity">
                                Pre-Controls Severity
                            </label>
                            <select class="mt-2 text-xs text-gray-700 sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400" wire:model="editing.pre_severity" name="editing.pre_severity">
                                <option value="0">-- Choose Rating --</option>
                                <option value="1">1 - Low</option>
                                <option value="2">2 - Low / Medium</option>
                                <option value="3">3 - Medium</option>
                                <option value="4">4 - Medium / High</option>
                                <option value="5">5 - High</option>

                            </select>
                            @error('editing.pre_severity')<span class="mt-1 text-red-500 text-sm">{{$message}}</span> @enderror
                        </div>
                        <div class="my-2 row flex justify-center">
                            <div class="{{$preRiskFormat}}">{{$preRiskRating}}</div>
                        </div>

                        <div class="mt-4  border border-gray-600 bg-gray-100 p-2 rounded-lg">
                            <div>
                                <label class="block font-medium text-sm text-gray-700" for="ControlType">
                                    Control Types
                                </label>
                                <select wire:model="controlType" name="controlType"
                                        class="w-full mt-2 text-sm text-gray-700 sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400">
                                    <option disabled value="">-- Choose Control Type --</option>
                                    @foreach($controlTypes as $type)
                                        <option value="{{$type->id}}">{{$type->type}}</option>
                                    @endforeach

                                </select>
                                @error('controlType')<span class="mt-1 text-red-500 text-sm">{{$message}}</span> @enderror
                            </div>

                            <div>
                                <label class="mt-1 block font-medium text-sm text-gray-700" for="addControls">
                                    Controls
                                </label>
                                <select wire:model="selectedControl" name="selectedControls" multiple="multiple" size="10"
                                        class="w-full mt-2 text-xs overflow-y-auto text-gray-700 sm:text-base pl-2 pr-8 rounded-lg border border-gray-400 w-full focus:outline-none focus:border-blue-400">
                                    <option disabled value="">-- Choose Control --</option>

                                    @foreach($controlsList as $control)
                                        @if(!in_array($control, $selectedControls))
                                            <option value="{{$control['id']}}">
                                                <span class="capitalize">{{$control['control']}}</span>
                                            </option>
                                        @endif
                                    @endforeach

                                </select>
                                <span class="text-xs text-gray-500 italic">
                                    Hold Ctrl to select multiple control measures
                                </span>
                                @error('selectedControls')<span class="mt-1 text-red-500 text-sm">{{$message}}</span> @enderror
                            </div>

                            <div class="row flex justify-end">
                                <x-button.primary wire:click="addToControls" class="px-2 py-1 text-sm border-blue-500 bg-blue-400" type="button">Add</x-button.primary>
                            </div>

                            <div>
                                @if(count($selectedControls) > 0)
                                    <div class="block font-medium text-sm text-gray-700">Added Controls</div>
                                    @foreach($selectedControls as $control)
                                        <div class="row-end-5 flex justify-between items-center px-1 py-1 mb-1 bg-white border border-gray-200 rounded-md text-sm text-gray-700 italic">
                                            <div>{{$control['control']}}</div>
                                            <x-button.secondary class="text-xs bg-red-500 px-1 py-1 text-white hover:bg-red-400 hover:text-white" type="button" wire:click="removeControl({{$loop->iteration-1}})">Delete</x-button.secondary>
                                        </div>
                                    @endforeach
                                @endif
                            </div>
                        </div>

                        <div class="mt-4">
                            <label class="block font-medium text-sm text-gray-700" for="editing.post_probability">
                                Post Controls Probability
                            </label>
                            <select wire:model="editing.post_probability" name="editing.post_probability"
                                    class="mt-2 text-xs text-gray-700 sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400">
                                <option value="0">-- Choose Rating --</option>
                                <option value="1">1 - Low</option>
                                <option value="2">2 - Low / Medium</option>
                                <option value="3">3 - Medium</option>
                                <option value="4">4 - Medium / High</option>
                                <option value="5">5 - High</option>

                            </select>
                            @error('editing.post_probability')<span class="mt-1 text-red-500 text-sm">{{$message}}</span> @enderror
                        </div>

                        <div class="mt-4">
                            <label class="block font-medium text-sm text-gray-700" for="editing.post_severity">
                                Post Controls Severity
                            </label>
                            <select wire:model="editing.post_severity" name="editing.post_severity"
                                    class="mt-2 text-gray-700 text-xs sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400">
                                <option value="0">-- Choose Rating --</option>
                                <option value="1">1 - Low</option>
                                <option value="2">2 - Low / Medium</option>
                                <option value="3">3 - Medium</option>
                                <option value="4">4 - Medium / High</option>
                                <option value="5">5 - High</option>

                            </select>
                            @error('editing.post_severity')<span class="mt-1 text-red-500 text-sm">{{$message}}</span> @enderror
                        </div>
                        <div class="my-2 row flex justify-center">
                            <div class="{{$postRiskFormat}}">{{$postRiskRating}}</div>
                        </div>
                    </div>
                </x-slot>
                <x-slot name="footer" class="mt-auto">
                    <x-button.secondary wire:click="$set('showEditModal', false)">Cancel</x-button.secondary>
                    <x-button.primary type="submit">Save</x-button.primary>
                </x-slot>
            </x-modal.dialog>
        </form>
    </div>
</div>

The problem is in the modal code as if I comment the modal out the page will load.

Any ideas anyone???

0 likes
7 replies
Snapey's avatar

What about the view that loads the component?

finchy70's avatar

Its extends the app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">

        <!-- Styles -->
        <link rel="stylesheet" href="{{ asset('/css/app.css') }}">
        <link rel="stylesheet" href="{{ asset('/css/trix.css') }}">
        <link rel="stylesheet" href="{{ asset('/css/my.css') }}">

        @yield('styles')

        <!-- Scripts -->
        <script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>
        <script src="{{ asset('js/app.js') }}" defer></script>
        <script src="{{asset('/js/trix.js')}}"></script>
        <script src="{{ asset('js/attachments.js') }}"></script>
        @yield('scripts')
        @livewireStyles
    </head>
    <body class="font-sans antialiased">
        <div class="bg-gray-50">
            @include('layouts.navigation')
{{--            <x-user-alert></x-user-alert>--}}

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="max-w-7xl mx-auto py-6 px-6 sm:px-6 lg:px-8">
                    {{ $header ?? '' }}
                </div>
            </header>

            <!-- Page Content -->
            <main class="max-w-7xl mx-auto py-6 px-6 sm:px-6 lg:px-8">
                {{ $slot }}
            </main>
        </div>
        @livewireScripts
    </body>
</html>

and loads from this route.

Route::get('/risks', CreateRisk::class)->name('risks.index');
finchy70's avatar
finchy70
OP
Best Answer
Level 12

Turns out the problem was the class on the footer x-slot.

 <x-slot name="footer" class="mt-auto">

Changing this line to <x-slot name="footer"> fixed the issue.

PeterJames's avatar

Check the Laravel version.

I had the same problem and the problem went away when I created a new project and tested the component there.

Slot attributes on components was released with Laravel 8.56

My project was originally on 8.53.1 and the new project was 8.58.0

So, check the Laravel framework version if you get the following error message:

Unable to locate a class or view for component [slot].

1 like
Snapey's avatar

@peterjames its a 3 month old question. slot attributes had not even been dreamt of then

PeterJames's avatar

True.

And I hope that anybody who starts using them on a version older than 8.56 will find this thread quickly and not waste as much time as I did before upgrading to 8.56 or greater.

I upgraded that codebase to 8.58 as well now and it works OK, so I am sure that was the problem in my case.

JustinM's avatar

I just ran into this same issue working through the Laravel 8.x docs on components. Thanks for the info PeterJames, I too was on 8.53.1

Please or to participate in this conversation.