Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

AungHtetPaing__'s avatar

hiding flash message with setTimeout doesn't work

Hello, I has flash message component that works with both event & inertia shared data. But it doesn't work if I make redirect to some route instead of redirect back.

When i log this.success & this.error in handler i see message but flash doesn't appear. So I put $page.props.flash.success directly to template. It works this time but doesn't disappear after 3 seconds.

here is my flash message component

<template>
	<transition name="slide-fade">
		<div
			class="bg-white border fixed right-5 rounded-lg shadow space-x-2 top-5 z-50"
		>
			<div
				class="flex items-center justify-between max-w-3xl"
			>
				<div
					v-if="(success || $page.props.flash.success) && show"
					class="flex items-center mr-4"
				>
					<svg
						class="bg-green-500 border fill-current flex-shrink-0 h-6 ml-4 mr-2 p-1.5 rounded-full text-white"
						xmlns="http://www.w3.org/2000/svg"
						viewBox="0 0 20 20"
					>
						<polygon points="0 11 2 9 7 14 18 3 20 5 7 18" />
					</svg>
					<div class="py-3 text-gray-700 text-sm font-medium">
						{{ success || $page.props.flash.success }}
					</div>
				</div>
				<div
					v-if="(error || $page.props.flash.error || Object.keys($page.props.errors).length > 0) && show"
					class="flex items-center mr-4"
				>
					<svg
						xmlns="http://www.w3.org/2000/svg"
						class="bg-red-500 border fill-current flex-shrink-0 h-6 ml-4 mr-2 p-1.5 rounded-full text-white"
						fill="none"
						viewBox="0 0 24 24"
						stroke="currentColor"
						stroke-width="3"
					>
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							d="M6 18L18 6M6 6l12 12"
						/>
					</svg>
					<div
						v-if="error"
						class="py-3 text-gray-700 text-sm font-medium"
					>
						{{ error }}
					</div>
					<div
						v-else
						class="py-3 text-gray-700 text-sm font-medium"
					>
						<span v-if="Object.keys($page.props.errors).length === 1">
							There is one form error.
						</span>
						<span v-else>There are {{ Object.keys($page.props.errors).length }} form errors.</span>
					</div>
				</div>
			</div>
		</div>
	</transition>
</template>

<script>
export default {
    data(){
        return {
            show: true,
            success: '',
            error: '',
            timeOut: '',
        }
    },

    watch: {
        '$page.props.flash': {
            handler() {
                console.log('hi')
                this.show = true
				// this.success = this.$page.props.flash.success
				// this.error = this.$page.props.flash.error
                if (this.timeOut) {
                    clearTimeout(this.timeOut)
                }
                this.hide()
            },
            deep: true
        },
    },

    created(){
        window.events.on('flash' , data => this.flash(data))
    },

    methods: {
        flash(data){
            console.log('flash')
            if (data.status === 'success') {
                this.success = data.message
            } else {
                this.error = data.message
            }

            if (this.timeOut) {
                clearTimeout(this.timeOut)
            }
            this.show = true
            this.hide()
        },

        hide() {
            console.log('called')
            this.timeOut = setTimeout(() => {
                this.show = false
                console.log('hided')
            }, 3000)
        }
    },
}
</script>

<style scoped>
.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all .5s;
}
.slide-fade-enter,
.slide-fade-leave-to {
  /* transform: translateY(-100px); */
  transform: translateX(50px);
  opacity: 0;
}
</style>

How can I hide it? I don't understand why it doesn't work with redirect route and why it doesn't disappear. Plz,

0 likes
1 reply
AungHtetPaing__'s avatar

I made it work with alpinejs

<div
					v-if="(success || $page.props.flash.success)"
					x-data="{shown: false, timeout: null}"
					x-init="clearTimeout(timeout); shown = true; timeout = setTimeout(() => { shown = false }, 2000);"
					x-show.transition.opacity.out.duration.1500ms="shown"
					class="flex items-center mr-4"
				>
					<svg
						class="bg-green-500 border fill-current flex-shrink-0 h-6 ml-4 mr-2 p-1.5 rounded-full text-white"
						xmlns="http://www.w3.org/2000/svg"
						viewBox="0 0 20 20"
					>
						<polygon points="0 11 2 9 7 14 18 3 20 5 7 18" />
					</svg>
					<div class="py-3 text-gray-700 text-sm font-medium">
						{{ success || $page.props.flash.success }}
					</div>
				</div>

but I still want to know why vue component data is not updated in template (when I make console.log i see everything work).

Please or to participate in this conversation.