nstuyvesant
nstuyvesant

Reputation: 1516

Using Bootstrap 5 Toast with asynchronously imported JavaScript library

Getting this error when using Bootstrap 5's native JavaScript to invoke a Toast from within a SvelteKit route...

Unhandled Promise Rejection: TypeError: Object is not a constructor (evaluating 'new Toast(toastDiv)')

Here's what I'm doing...

<script lang="ts">
  import { onMount } from 'svelte'

  let title = 'Title of toast'
  let body = 'Contents of toast'
  let Toast

  onMount(async() => {
    Toast = await import('bootstrap/js/dist/toast')
    const toastDiv = <HTMLDivElement> document.getElementById('authToast')
    const toast = new Toast(toastDiv)
    toast.show()
  })
</script>

<div id="authToast" class="toast position-fixed top-0 end-0 m-3" role="alert" aria-live="assertive" aria-atomic="true">
  <div class="toast-header bg-primary text-white">
    <img src="..." class="rounded me-2" alt="...">
    <strong class="me-auto">{title}</strong>
    <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
  </div>
  <div class="toast-body">
    {body}
  </div>
</div>

Because I'm using SvelteKit, I have to asynchronously load Bootstrap in onMount() or it would lead to an error because SvelteKit pages have server-side rendering. My code is functionally similar to Bootstrap's (albeit) modal example of:

import Modal from 'bootstrap/js/dist/modal'
const modal = new Modal(document.getElementById('myModal'))

Any idea what I'm doing wrong?

Upvotes: 1

Views: 928

Answers (1)

nstuyvesant
nstuyvesant

Reputation: 1516

Apparently, my onMount function needed to look like this...

  onMount(async() => {
    Toast = (await import('bootstrap/js/dist/toast')).default
    const toastDiv = <HTMLDivElement> document.getElementById('authToast')
    const toast = new Toast(toastDiv)
    toast.show()
  })

Upvotes: 1

Related Questions