Skip to content

Promise-based Notifications

Example

ts
async function sendMessage(user: User, message: string) {
  const notification = push.promise("We're sending your message, hold on...")

  try {
    const { chatId } = await sendMsg(user.id, message)

    notification.resolve({
      message: `Your message has been successfully sent to ${user.name}.`,
      props: {
        chatUrl: `/chat/${chatId}`
      }
    })
  } catch (error) {
    console.error(error)
    notification.reject(getErrorMsg(error))
  }
}
vue
<script setup lang="ts">
import Spinner from './Spinner.vue'
import SuccessIcon from './SuccessIcon.vue'
import ErrorIcon from './ErrorIcon.vue'

import type { NotivueItem } from 'notivue'

interface MessageNotificationProps {
  chatUrl?: string
}

const notification = defineProps<{
  item: NotivueItem<MessageNotificationProps>
}>()

const isLoading = computed(() => notification.item.type === 'promise')
const isSuccess = computed(() => notification.item.type === 'promise-resolve')
const isError = computed(() => notification.item.type === 'promise-reject')
</script>

<template>
  <div>
    <Spinner v-if="isLoading" />
    <SuccessIcon v-else-if="isSuccess" />
    <ErrorIcon v-else />

    <div>
      <p :aria-live="item.ariaLive" :role="item.ariaRole">
        {{ item.message }}
      </p>

      <RouterLink
        v-if="isSuccess && item.props.chatUrl"
        :to="item.props.chatUrl"
        @click="item.close"
      >
        View Chat
      </RouterLink>
    </div>

    <button v-if="isSuccess || isError" @click="item.close">Dismiss</button>
  </div>
</template>