skip to Main Content

Basically I use SweetAlert2 to fire a toast whenever there is errors, single error or success messages.

It seems to work fine until I do a Redirect::route('auth.index')->with([...]), then the success or error/errors message won’t fire at all.

I can open the VueDevTools and confirm that the error/success is visible though.
enter image description here

Works fine if I do redirect back to the same page with the errors/success message Redirect::back()->with([...]).

Everything works until I want to go to another view with the flash message. What am I missing or doing wrong? I’ve been searching and going through the Inertia docs and vue docs but can’t find anything related other than the data sharing, which I’ve already done.

Thanks in advance if anyone got the time to help.

HandleInertiaRequests.php

/**
 * Defines the props that are shared by default.
 *
 * @see https://inertiajs.com/shared-data
 * @param  IlluminateHttpRequest  $request
 * @return array
 */
public function share(Request $request): array
{
    return array_merge(parent::share($request), [
        'flash' => [
            'message' => fn () => $request->session()->get('message'),
            'type' => fn () => $request->session()->get('type'),
            'title' => fn () => $request->session()->get('title'),
        ],
    ]);
}

PasswordController.php

/**
 * Send a reset link to the given user.
 *
 * @param  AppHttpRequestsPasswordEmailRequest  $request
 * @return IlluminateHttpRedirectResponse
 */
public function email(EmailRequest $request)
{
    # Send reset link to user
    $status = Password::sendResetLink(
        $request->only('email')
    );

    # No leak if email exists or not.
    if ($status === Password::RESET_LINK_SENT || $status === Password::INVALID_USER) {
        return Redirect::route('auth.index')->with([
            'message' => __($status),
            'type' => 'success',
            'title' => 'Success',
        ]);
    }

    # Error
    return Redirect::back()->withErrors([__($status)]);
}
...

Layout.vue

<template>
    <Swal :swalErrors="$page.props.errors" :swalFlash="$page.props.flash" />
</template>

<script>
import Swal from '../Component/Swal.vue';
</script>

Swal.vue

<template>
</template>

<script>
export default {
    props: {
        swalErrors: Object,
        swalFlash: Object
    },

    watch: {
        swalErrors: {
            handler: function (errors) {
                if (errors) {
                    this.toast(Object.values(errors).join(' '));
                }
            },
        },

        swalFlash: {
            handler: function (flash) {
                if (flash) {
                    this.toast(flash.message, flash.title, flash.type);
                }
            },
        }
    },

    methods: {
        toast: function (html, title, icon, timer) {
            title = title || 'Error';
            icon = icon || 'error';
            timer = timer || 4000;
            
            this.$swal.fire({
                position: 'top-end',
                toast: true,
                icon: icon,
                title: title,
                html: html,
                showClass: { popup: 'animate__animated animate__fadeInDown' },
                hideClass: { popup: 'animate__animated animate__fadeOutUp'  },
                timer: timer,
                timerProgressBar: true,
                showConfirmButton: false,
            });
        }
    }
}
</script>

2

Answers


  1. Chosen as BEST ANSWER

    A kind sir from reddit suggested using a persistent layout (from the Inertia docs). I did and it worked. enter link description here


  2. So basically the flash message is only one time use. Once you refresh or redirect to other page it will be remove. If you want to persist the session so that you can use it to the other page please refer to this Laravel Docs

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search