I'm new to Bootstrap and trying to activate the .collapse()
function from Javascript in an Angular controller when a user clicks on a link. This should close the collapsible navbar when one of the links is clicked (because the routing is controlled by Angular and doesn't cause a page refresh).
The following error shows:
ERROR TypeError: $(...).collapse is not a function
at HTMLAnchorElement.<anonymous> (header.component.ts:18)
at HTMLAnchorElement.dispatch (jquery.js:5183)
at HTMLAnchorElement.elemData.handle (jquery.js:4991)
at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:4740)
at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at ZoneTask.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496)
at invokeTask (zone.js:1540)
at HTMLAnchorElement.globalZoneAwareCallback (zone.js:1577)
Relevant part of HTML template:
<div class='collapse navbar-collapse' id='mainNavbar'>
<div class='navbar-nav'>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "Home" }'>
<a class='nav-link' routerLink='/'>Home</a>
</div>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "Request" }'>
<a class='nav-link' routerLink='/request'>Request</a>
</div>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "Volunteer" }'>
<a class='nav-link' routerLink='/volunteer'>Volunteer</a>
</div>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "About" }'>
<a class='nav-link' routerLink='/about'>About</a>
</div>
</div>
</div>
Relevant part of controller:
// importing jquery from npm module
import * as $ from 'jquery';
// inside the controller class
ngOnInit() {
$('.nav-link').click(() => $('.collapse').collapse('toggle'));
}
Included scripts (in .angular-cli.json
):
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/popper.js/dist/umd/popper.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js"
]
I've seen multiple questions just like this, but almost always the answers say to make sure jQuery is included before Bootstrap, and that Bootstrap is not included twice. Neither is the case here.
Other jQuery functionality (normal collapse functionality) is working properly. And the same error comes up if I try to do use the .dropdown()
function on dropdowns.
What is the issue here?
If you need: Angular 5, Bootstrap v4.0.0 (npm module), jQuery v3.3.1 (npm module)
You need to use declare let $ : any;
instead of your import
I assume that if you use
import jquery as $ from 'jquery';
then it means that $ will only contain the code defined in the jquery package, and not the additional plugins declared by bootstrap (or by any other jquery plugins).
If you use
declare let $ : any;
then $ represents the normal jQuery function PLUS the additional plugins (collapse, dropdown, ...) added by other libraries
If you don't want to use any
, and you need to explicitely call some plugin methods, you need to extend jQuery's interface
interface JQuery
{
carousel(options : any);
}
declare let $: JQuery;
Note if you can avoid it, you should avoid using jquery or jquery plugins when a native angular approach is available
For boostrap, like ConnorsFan mentionned, you can use ng-bootstrap as a replacement. It requires bootstrap's CSS file, but dynamic components have been rewritten in native angular, without the need of jQuery
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With