Bootstrap with Angular 9

11/02/20 dannyVersion Française

What are we going to do ?

We will integrate Bootstrap in our Web Application.
We will use the Angular version 9.0.1 javascript framework.

This is Step 4 of our  Angular guide which will allow us to obtain a PWA Web Application.
We will use an existing project whose characteristics are

  • Generated with Angular CLI
  • Routing
  • Lazy loading

All created sources are indicated at the end of the tutorial.

The application is at the following address


Before you start

The pages of a website are written with 3 languages

  • HTML : it allows to create and represent the content of a web page and its structure.
  • CSS : it is used to describe the layout of a page.
  • Javascript : It allows you to create interactive features in the page.

Many tools can simplify the life of a Frontend developer.
In particular the CSS Frameworks which constitute somehow toolboxes.
The CSS frameworks are extremely numerous, among them we could quote

  • Foundation
  • Materialize CSS
  • Bootstrap
  • Pure

Bootstrap is one of the most famous and used CSS frameworks.


Installation

Bootstrap is under open source license since 2011.

The current version is v 4.3.1
The bootstrap site is https://getbootstrap.com/

We will use a classic interface, the goal is not here to develop html and css code.

The sample code that we will use is the bootstrap starter template proposed on the bootstrap site
https://getbootstrap.com/docs/4.3/examples/starter-template/

For Icons Bootstrap advocates some libraries, we will opt for Font Awesome
https://getbootstrap.com/docs/4.3/extend/icons/

We will add the necessary dependencies

  • Jquery version 3.4.1
  • Bootstrap version 4.3.1
  • Fontawesome version 5.11.2

The latest versions of these tools are available below


After the update we will modify the descriptors in package.json

# Add dependencies in package.json
npm install --save jquery
npm install --save bootstrap
npm install --save @fortawesome/fontawesome-free
package.json
    "@fortawesome/fontawesome-free": "5.12.1",
    "bootstrap": "4.4.1",
    "jquery": "3.4.1",
    "rxjs": "6.5.4",
    "tslib": "1.10.0",
    "zone.js": "0.10.2"

Update

We will modify the file angular.json to call the files necessary for the operation of our html pages.

CSS formatting files

  • styles.css (specific to our project)
  • font-awesome.css
  • bootstrap.min.css

Javascript script files

  • jquery.min.js
  • bootstrap.min.js
  • index.js (specific to our project)
angular.json
"build": {
  "builder": "@angular-devkit/build-angular:browser",
  "options": {
    "outputPath": "dist/angular-starter",
    "index": "src/index.html",
    "main": "src/main.ts",
    "polyfills": "src/polyfills.ts",
    "tsConfig": "tsconfig.app.json",
    "assets": [
      "src/favicon.ico",
      "src/assets"
    ],
    "styles": [
      "src/styles.css",
      "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
      "node_modules/bootstrap/dist/css/bootstrap.min.css",
      "src/assets/params/css/index.css"
    ],
    "scripts": [
      "node_modules/jquery/dist/jquery.min.js",
      "node_modules/bootstrap/dist/js/bootstrap.min.js",
      "src/assets/params/js/index.js"
    ]
  },
  
src/styles.css
body {
  color: black;
  font-weight: 400;
  padding-top: 5rem;
}
src/assets/params/js/index.js
$(function () {
  var navMain = $("#navbarsExampleDefault");
  navMain.on("click", "a", null, function () {
    navMain.collapse('hide');
  });
});

We will modify the following files which will contain the new interface

  • app.component.html
  • home.component.html
  • home.component.ts
  • environment.prod.ts
  • environment.ts
  • app.component.spec.ts

We will add the images used in the assets/params/images/logo directory

  • ganatan.png
  • bootstrap.png
  • angular.png
src/app/app.component.html
<div class="app">

  <header>
    <nav class="navbar navbar-expand-md fixed-top navbar-dark " style="background-color: #212121;">
      <a class="navbar-brand" routerLink="/">
        <span class="mr-1" style="color:white">ganatan</span>
        <img src="./assets/params/images/logo/ganatan.png" width="20" height="20" alt="">
      </a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
        aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarsExampleDefault">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item active">
            <a class="nav-link" routerLink="/">
              <i class="fas fa-home mr-1"></i>home
            </a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" routerLink="/about">
              <i class="far fa-question-circle mr-1"></i>About
            </a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" routerLink="/contact">
              <i class="fas fa-envelope mr-1"></i>Contact
            </a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" routerLink="/signin">
              <i class="fas fa-user mr-1"></i>Sign in
            </a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" href="https://github.com/ganatan">
              <i class="fab fa-github mr-1"></i>Github
            </a>
          </li>
        </ul>
      </div>
    </nav>
  </header>

  <main>
    <div class="container-fluid">
      <router-outlet></router-outlet>
    </div>
  </main>

  <div class="footer">
    <div class="container">
      <div class="row">
        <div class="col-12">
          <p class="text-center text-white">&copy; 2020 - www.ganatan.com</p>
        </div>
      </div>
    </div>
  </div>
src/app/modules/general/home/home.component.html
<div class="row">
  <div class="col-md-12 text-center">
    <div class="row pt-1 mb-2">
      <div class="col-md-4 text-center mb-2">
        <h1 class="h5">
          <i class="fab fa-android fa-lg mr-2 text-primary"></i>
          {{ name }}<i class="fab fa-apple fa-lg ml-2 mr-1 text-primary"></i>
        </h1>
      </div>
      <div class="col-md-4 text-center">
        <h2 class="h5">{{angular}}&nbsp;&nbsp;<img src="./assets/params/images/logo/angular.png" width="36" height="36"
            alt=""></h2>
      </div>
      <div class="col-md-4 text-center">
        <h2 class="h5">{{bootstrap}}&nbsp;&nbsp;<img src="./assets/params/images/logo/bootstrap.png" width="28"
            height="28" alt=""></h2>
      </div>
    </div>
    <hr>
    <div class="row mb-1">
      <div class="col-md-12 text-center">
        <h3 class="h6">Features&nbsp;&nbsp;<i class="fas fa-list"></i></h3>
      </div>
    </div>
    <p>
      home works!
    </p>
  </div>
</div>
src/app/modules/general/home/home.component.ts
import { Component, OnInit } from '@angular/core';
import { environment } from '../../../../environments/environment';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  name = environment.application.name;
  angular = environment.application.angular;
  bootstrap = environment.application.bootstrap;

  constructor() { }

  ngOnInit() {
  }

}
src/environments/environments.ts
export const environment = {
  production: false,
  application:
  {
    name: 'angular-starter',
    angular: 'Angular 9.0.1',
    bootstrap: 'Bootstrap 4.4.1',
    fontawesome: 'Font Awesome 5.12.1',
  }
};
src/environments/environments.prod.ts
export const environment = {
  production: true,
  application:
  {
    name: 'angular-starter',
    angular: 'Angular 9.0.1',
    bootstrap: 'Bootstrap 4.4.1',
    fontawesome: 'Font Awesome 5.12.1',
  }
};
src/app/app.component.spec.ts
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { RouterTestingModule } from '@angular/router/testing';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 'angular-starter'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('angular-starter');
  });

});

Tests


It only remains to test the different Angular scripts.

# Development
npm run start
http://localhost:4200/

# Tests
npm run lint
npm run test
npm run e2e

# Compilation
npm run build