why my popovers from bootstrap 5 return a Uncaught TypeError?

Viewed 1524

I want to use Bootstrap 5 popovers in my Angular app.

Here's what I do:

my index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>my website</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
  <script>
    var popover = new bootstrap.Popover(document.querySelector('.popoverable'), {
      container: 'body'
    })
  </script>
</body>
</html>

app.component.html

<button type="button" class="btn btn-secondary popoverable" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Bottom popover">
  Popover on bottom
</button>

Then on my page I see my styled button, but the popover doesn't appear and in the console I get a Uncaught TypeError: this._element is undefined.

Does anybody have a solution to my issue ?

2 Answers

You are using the beta version of bootstrap 5 which doesn't require jQuery and uses its own javascript file.

To initialize bootstrap's js you have to use bs.

Replace:

  • data-toggle to data-bs-toggle
  • data-placement to data-bs-placement
  • data-content to data-bs-content

Your code:

<button type="button" class="btn btn-secondary popoverable" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Bottom popover">
  Popover on bottom
</button>

Updated Code:

<button type="button" class="my-5 d-block btn btn-secondary popoverable" data-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Bottom popover">
  Popover on bottom
</button>

enter image description here

This is a bit old, but I just ran into this and figured it out so I thought I'd share for posterity.

Turns out this happens when you call new bootstrap.Popover before the element is on the page. It doesn't work for "future" elements to be rendered on the page, which in your case I believe must happen through Angular in your <app-root> element. When the <script> tag executes, there is no .popoverable in the DOM.

In my case, I had to make sure to defer Popover's initialization til after DOMContentLoaded.

document.addEventListener("DOMContentLoaded", function (event) {
  let popoverTriggerList = [].slice.call(
    document.querySelectorAll('.popoverable')
  );
  let popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
    return new bootstrap.Popover(popoverTriggerEl);
  });
});

In your case, you would have to make it happen after the app-component has been rendered into the DOM (I'm not familiar enough with Angular to tell you where that would be, but you'd need to hook into the initialization life-cycle of the component, and perhaps also make sure to "disconnect" the Popover if/when the app-component gets unloaded in order to avoid memory leaks).

Related