Mastodon

Angular and Bootstrap - Use ng-bootstrap

In this article I wrote about my attempt to add a navbar to my Angular app and how I ended up with adding the full JQuery library to be able to use Bootstrap components. Already when releasing this article I knew that this is not the best way to get a working navbar. In this article, I explain why using ng-bootstrap seems to be the best way to add Bootstrap components to an Angular application.

In my first article regarding this topic, I mentioned Chris Sevilleja and his article “How to correctly use BootstrapJS and AngularJS together”. Although it has become outdated, this quote still is true:

The way you manipulate data with jQuery is essentially grabbing and injecting into your DOM based on events. So when we use the Bootstrap JavaScript components, like a button, we are saying “when this button is clicked, toggle this button to active”. This will set the button to active by adding an .active class and checking an input box (if your button is an input checkbox). With Angular, manipulating data isn’t a grab and inject sort of affair. Things are data-bound so we don’t need to do all that barbaric grab and inject stuff. We should be able to bind a variable to each component (button or collapse) and then toggle it based on the true/false nature of that variable. This is why we can’t just use Bootstrap JavaScript. It relies on jQuery and we don’t want jQuery rummaging around our Angular projects. If we try to bind variables to the components, it won’t work.

Chris recommended UI Bootstrap, which is outdated by now: Angular apps greater equal version 2 should use ng-bootstrap which has been developed by the same team.

ng-bootstrap solves the problem with JQuery: “Angular - specific widgets built from ground and using Bootstrap 4 CSS. APIs that makes sense in the Angular ecosystem. No dependencies on 3rd party JavaScript.” Also, bootstrap.js or bootstrap.min.js should not be added to the project: “… the goal of ng-bootstrap is to completely replace JavaScript implementation for components. Nor should you include other dependencies like jQuery or popper.js. It is not necessary and might interfere with ng-bootstrap code.”

After installing ng-bootstrap via NPM, I finally got my “good” navbar with the following HTML:

<div class="container" style="padding-left: 0; padding-right: 0;">
    <header class="navbar navbar-light navbar-fixed-top navbar-expand-lg">
 
        <a class="navbar-brand" [routerLink]="['/']" (click)="navbarCollapsed = true">ng-bootstrap</a>
 
        <button class="navbar-toggler navbar-toggler-right" type="button" (click)="navbarCollapsed = !navbarCollapsed"
                [attr.aria-expanded]="!navbarCollapsed" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
 
        <div class="navbar-collapse" [ngbCollapse]="navbarCollapsed" id="navbarContent">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item" [routerLinkActive]="['active']">
                    <a class="nav-link" [routerLink]="['/getting-started']" (click)="navbarCollapsed = true">Getting Started</a>
                </li>
                <li class="nav-item" [routerLinkActive]="['active']">
                    <a class="nav-link" [routerLink]="['/components']" (click)="navbarCollapsed = true">Components</a>
                </li>
                <li class="nav-item d-lg-none" *ngFor="let component of components" [routerLinkActive]="['active']">
                    <a class="nav-link" [routerLink]="['/components', component.toLowerCase()]" (click)="navbarCollapsed = true"></a>
                </li>
            </ul>
 
            <span class="github-buttons d-none d-lg-inline">
        <a class="github-button"
           href="https://github.com/ng-bootstrap/ng-bootstrap"
           target="_blank"
           data-size="large"
           data-show-count="true"
           data-count-aria-label="# stargazers on GitHub"
           aria-label="Star ng-bootstrap/ng-bootstrap on GitHub">Star</a>
        <a href="https://twitter.com/intent/tweet?button_hashtag=ngbootstrap"
           class="twitter-hashtag-button"
           data-size="large"
           data-text="I&#39;m checking out ng-bootstrap, THE Angular UI framework for Bootstrap CSS"
           data-url="https://ng-bootstrap.github.io"
           data-show-count="true">Tweet #ngbootstrap</a>
      </span>
        </div>
    </header>
</div>

TL;DR

Use ng-bootstrap to have Bootstrap functionality in Angular applications