https://cli.angular.io/). If you have not installed Angular CLI on your system first make sure that the command line interface is installed by executing the following command:
$ npm install -g @angular/cli@latest
Having installed Angular CLI you can now make use of the ng command. By using this command we’re able to initiate a new Angular project:
$ ng new ng-fb-bootstrap
To initiate a new project we need to use the command line parameter new and specify the name of the new project.
Change into the newly created project folder:
$ cd ng-fb-bootstrap
In the project folder you can execute the following command to launch the development web server:
$ ng serve
The server is started and the application can be accessed on http://localhost:4200 as you can see in the following screenshot:
Next step is to include Firebase in our project. Two steps are needed here:
To create a new Firebase project go to the Firebase website https://firebase.google.com and create a new account / sign in with your Google credentials. After you’re being logged in successfully you can click on the link Go To Console to access the Firebase back-end:
Here you can click on Add project to add a new Firebase project or select one of the existing projects. You’re taken to the project console next:
Click on the link Add Firebase to your web app to access the following dialog:
Here you can find the JavaScript code which is needed to initialize the Firebase project for your website. However, to include this Firebase configuration in the Angular project we do only need a part of that code snippet. Copy the key-value pairs inside the config object and insert those pairs inside the file environments/environment.ts
in the following way:
export const environment = {
production: false,
firebase: {
apiKey: "[...]",
authDomain: "[...]",
projectId: "[...]",
storageBucket: "[...]",
messagingSenderId: "[...]",
appId: "[...]"
}
};
The key-value pairs are inserted into a new property named firebase. The same needs to be inserted into environments/environment.prod.ts
:
export const environment = {
production: true,
firebase: {
apiKey: "[...]",
authDomain: "[...]",
projectId: "[...]",
storageBucket: "[...]",
messagingSenderId: "[...]",
appId: "[...]"
}
};
That’s needed to make the Firebase settings available whether we’re building during development or for production.
Next, let’s add the libraries to our project by executing the following command:
$ ng add @angular/fire
That command is downloading and installing the @angular/fire package, which includes both the Firebase SDK and AngularFire library.
Insert the following import statements into app.module.ts
:
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { getAuth, provideAuth } from '@angular/fire/auth';
Also add the Firebase modules to the imports array of the @NgModule decorator in the following way:
@NgModule({
declarations: [
AppComponent,
AppNavbarComponent
],
imports: [
BrowserModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
provideAuth(() => getAuth())
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Please note that we’re using the new modular SDK approach for Firebase. To gain access to the environment object you need to add the following import statement as well:
import { environment } from './../environments/environment';
Let’s add the Bootstrap 5 library to our project by using NPM:
$ npm install bootstrap@5.3.2
To make the Bootstrap CSS classes available for the components in our project we need to include the Bootstrap CSS file from node_modules/bootstrap/dist/css/bootstrap.css
in our project. To do so add the following line in file angular.json
under the styles
array:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
To add a Bootstrap user interface to our sample application we’ll make use of the Bootstrap Starter Template which is available at https://getbootstrap.com/docs/5.3/examples/:
To setup a basic user interface with Bootstrap elements we’re going to use code from the Bootstrap Starter Template which can be found on the Examples page:
Clicking on the link Starter template opens up the starter template website in a new browser window. To access the HTML markup code of the starter template just open the browser’s source code view. From the source code view we can copy and paste the needed code parts into our application. First let’s copy the following code from the <body>
-section to the template code in app.component.html
:
<div class="d-flex justify-content-center align-items-center" style="height: 100vh;">
<div class="text-center">
<h1>Welcome to Angular</h1>
<p class="lead">This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a>
</div>
</div>
Furthermore we’d like to include the navigation bar from the starter template as well. We do that by first adding a new component to our application by using Angular CLI again:
$ ng generate component app-navbar
This command creates a new folder src/app/app-navbar/.
Within that folder you’ll find the following four files:
app-navbar.component.html
app-navbar.component.ts
app-navbar.component.css
The component’s template code can be found in file app-navbar.component.html
. Delete the default markup code from that file and copy and paste the following code excerpt from the Bootstrap starter template:
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav me-auto mb-2 mb-md-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
Now add the <app-navbar>
element to the template code of AppComponent:
<app-navbar></app-navbar>
<div class="container">
<div class="starter-template">
<h1>Bootstrap starter template</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>
</div>
Finally some CSS code needs to be added to styles.css
body {
padding-top: 80px;
}
.starter-template {
padding: 3rem 1.5rem;
text-align: center;
}
The result of the application in the browser should now comply with the Bootstrap starter template’s output:
There is one difference between the result we’re getting from our application and the original Bootstrap Starter Template. If you try to open the Dropdown menu item in the navigation bar you’ll notice that no dropdown menu appears. The reason for that is that we’ve only included the Bootstrap CSS file in our project. The JavaScript part of Bootstrap has not been added.
As the Bootstrap JavaScript library is making use of Popper.js and is manipulating the DOM directly, for an Angular application any direct DOM manipulations should be avoided and the complete control to update DOM elements should be given to the Angular framework. Therefore we need another way to include JavaScript-based Bootstrap elements (e.g. the dropdown element) in our Angular application.
The solution to this problem is to use Bootstrap 5 Angular directives. To make use of those directives you need to add the ng-bootstrap package to your project. The project’s website can be found at https://ng-bootstrap.github.io. The installation is done via Angular CLI:
ng add @ng-bootstrap/ng-bootstrap
This command will install ng-bootstrap and update your app.module.ts
file automatically. If it doesn’t, you can manually add the following import:
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
And add NgbModule to the imports array:
imports: [
BrowserModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore()),
provideAuth(() => getAuth()),
NgbModule
],
Now we can make use of the Bootstrap directives in our template code. For implementing the dropdown menu we’ll need to make use of the following three directives: ngbDropdown, ngbDropdownToggle, and ngbDropdownMenu:
<li class="nav-item dropdown" ngbDropdown>
<a class="nav-link dropdown-toggle" ngbDropdownToggle>Category</a>
<div class="dropdown-menu" ngbDropdownMenu>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
The result should now look like the following when you click on the menu Category:
Finally, let’s retrieve and display some sample data from the Firebase Firestore Database. Therefore we assume that the following data structure has already been created in the Firestore database:
{
"courses": [
{
"id": "angular-complete-guide",
"description": "Master Angular and build awesome, reactive web apps with the successor of Angular.js",
"title": "Angular - The Complete Guide",
"url": "https://codingthesmartway.com/courses/angular-complete-guide/"
},
{
"id": "learn-ionic-from-scratch",
"description": "Create Cross Platform Mobile Applications with Ionic, Angular, TypeScript and Firebase.",
"title": "Learn Ionic From Scratch",
"url": "https://codingthesmartway.com/courses/ionic/"
},
{
"id": "modern-react-with-redux",
"description": "Master the fundamentals of React and Redux with this tutorial as you develop apps with React Router, Webpack, and ES6",
"title": "Modern React With Redux",
"url": "https://codingthesmartway.com/courses/modern-react-with-redux/"
},
{
"id": "vuejs-complete-guide",
"description": "Vue.js is an awesome JavaScript Framework for building Frontend Applications! Vue.js mixes the Best of Angular + React!",
"title": "Vue.js - The Complete Guide",
"url": "https://codingthesmartway.com/courses/vuejs-complete-guide"
}
]
}
The corresponding data view in the Firebase console should look similar to this (but in Firestore format).
To retrieve and display this data in our application we’re adding a new Angular component:
$ ng generate component courses-list
This creates a new folder courses-list
in src/app
and you’ll find the component files within that folder.
First we need to adapt the implementation of class CoursesListComponent in file courses-list.component.ts
:
import { Component, OnInit } from '@angular/core';
import { Firestore, collectionData } from '@angular/fire/firestore';
import { collection } from 'firebase/firestore';
import { Observable } from 'rxjs';
interface Course {
id: string;
title: string;
description: string;
url: string;
}
@Component({
selector: 'app-courses-list',
templateUrl: './courses-list.component.html',
styleUrls: ['./courses-list.component.css']
})
export class CoursesListComponent implements OnInit {
coursesObservable: Observable<Course[]>;
constructor(private firestore: Firestore) { }
ngOnInit() {
const coursesCollection = collection(this.firestore, 'courses');
this.coursesObservable = collectionData(coursesCollection) as Observable<Course[]>;
}
}
Here we’re injecting the Firestore service into the class constructor. The class contains logic in the ngOnInit method to retrieve an observable for the collection of courses in the database. We’re using the collection
function to get a reference to the ‘courses’ collection, and then the collectionData
function to get an observable of the collection data.
The coursesObservable member is used to access data in the template code in file courses-list.component.html
:
<ul>
<div *ngFor="let course of coursesObservable | async">
<ngb-alert type="info" [dismissible]="false">
<h3><a href="#">{{course.title}}</a></h3>
<p>{{course.description}}</p>
<div>
<a href="{{course.url}}" target="_blank" class="btn btn-danger">Go To Course</a>
</div>
</ngb-alert>
</div>
</ul>
To access the coursesObservable in the template code we need to apply the async
pipe.
Finally, you need to include the <app-courses-list>
element in the template code in app.component.html
:
<app-courses-list></app-courses-list>
Now the result in the browser should look like the following:
In this first part we’ve started to build our Angular 17, Bootstrap 5 and Firebase application from scratch. You’ve learned how to setup the project, install the required libraries, and tie everything together. The resulting sample application can be used as an application skeleton for implementing your own features.
In the following parts of this series the application will be enhanced step-by-step. In the next part we’ll focus on adding routes to our application.
This post has been published first on CodingTheSmartWay.com and has been updated to reflect the latest versions of Angular, Bootstrap, and Firebase as of October 2024.