Search code examples
phplaravelvue.jssingle-page-applicationinertiajs

Laravel Inertia JS Flash Messages shows only once


Because InertiaJS doesn't refresh same route components, things like flash messages will show only once no matter how many time you pass messages from the backend. I tried everything but nothing works, All I need is to be able to trigger the same flash message again after I fail doing the same action.

Controller: This should be triggered as part of validation I'm making by some if statements, so basically I'm saying if the quantity requested more than stock quantity return this flash message.

                    return back()->with([
                        'error' => 'This item has only ' . $item->qty . ' items in stock'
                    ]);

The flash component:

<script setup>
import { ref, onMounted } from "vue";
defineProps({
    message: Object,
});

const showNotif = ref(false);

let msgs = ref([]);

onMounted(() => {
    showNotif.value = true;
    setTimeout(() => {
        showNotif.value = false;
    }, 6000);
});
</script>

<template>
    <div>
        <Transition
            mode="out-in"
            name="flash"
            tag="div"
            enter-active-class="animate__animated animate__fadeInUp"
            leave-active-class="animate__animated animate__fadeOutDown"
            appear
        >
            <p
                v-if="message.error && showNotif"
                class="cursor-pointer fixed bottom-3 right-3 bg-red-600 px-5 py-1 font-semibold text-white rounded-xl"
            >
                {{ message.error }}
            </p>
        </Transition>
        <Transition
            mode="out-in"
            name="flash"
            tag="div"
            enter-active-class="animate__animated animate__fadeInUp"
            leave-active-class="animate__animated animate__fadeOutDown"
            appear
        >
            <p
                v-if="message.success && showNotif"
                class="cursor-pointer fixed bottom-3 right-3 bg-green-600 px-5 py-1 font-semibold text-white rounded-xl"
            >
                {{ message.success }}
            </p>
        </Transition>
    </div>
</template>

This works fine, the flash shows up, spent few seconds and then disappear. but no matter how many times I click on the same button to get this flash message it never happens and my brain is about to explode!


Solution

  • From the documentation here, You will have to look for app/Http/Middleware/HandleInertiaRequests.php and make sure you have something like this.

    class HandleInertiaRequests extends Middleware
    {
        public function share(Request $request)
        {
            return array_merge(parent::share($request), [
                'flash' => [
                    'error' => fn () => $request->session()->get('error')
                ],
            ]);
        }
    }
    

    Basically, you are creating a shared_data prop called flash, which is an associative array (Object) with a message key.

    Note that you will only get data in your front end if you do with(['error => 'message here']). If you want a success you will also have to add it on its own.

    sample of the data you would get enter image description here