In this guide, we'll walk through the process of building a stock market application using Angular, a powerful front-end framework. Building a stock market application allows users to monitor stock prices, add stocks to their watchlist, and stay informed about market trends.
Project Preview:
Prerequisites:
- Basic knowledge of HTML, CSS, and JavaScript.
- Node.js and npm
- Angular
- MongoDB
- Express
Approach
- Component-based Architecture: We'll organize our application into reusable components, such as StocksComponent and WatchlistComponent.
- Routing: Angular's routing module will be used to navigate between different views of our application.
- HTTP Requests: We'll make HTTP requests to fetch stock data from a mock API and to add stocks to the watchlist.
- State Management: We'll manage the state of our application using Angular services and component interaction.
Steps to Set Up the Stock Market Portfolio App project
Step 1: Set Up the Express.js Backend. Create Server Folder and navigate to server
mkdir server
cd serve
Project Structure:
Step 2: Install the required dependencies:
npm init -y
npm install express mongoose cors body-parser
Updated dependencies will look like:
"dependencies": {
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.19.2",
"mongoose": "^8.3.2"
}
Code Example: Create index.js file with following code:
//index.js
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
const PORT = process.env.PORT || 5000;
app.use(cors());
app.use(bodyParser.json());
mongoose.connect("your mongodb link", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const stockSchema = new mongoose.Schema({
company: String,
description: String,
initial_price: Number,
price_2002: Number,
price_2007: Number,
symbol: String,
});
const Stock = mongoose.model("Stock", stockSchema);
app.get("/api/stocks", async (req, res) => {
try {
const stocks = await Stock.find();
res.json(stocks);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal Server Error" });
}
});
app.post("/api/watchlist", async (req, res) => {
try {
const {
company,
description,
initial_price,
price_2002,
price_2007,
symbol,
} = req.body;
const stock = new Stock({
company,
description,
initial_price,
price_2002,
price_2007,
symbol,
});
await stock.save();
res.json({ message: "Stock added to watchlist successfully" });
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal Server Error" });
}
});
app.get("/", (req, res) => {
res.sendFile(__dirname + "/../frontend/src/index.html");
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Run the Backend using the following command.
node server.js
Step 3: Run the following command to install Angular CLI globally:
npm install -g @angular/cli
Step 4: Create Angular App
ng new client
Project Structure:
Updated Dependencies:
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"bootstrap": "^5.3.3",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
},
Manage files and folders
- create stock folder with stocks.component.html and stocks.component.ts inside app
- create watchlist with watchlist.component.html and watchlist.component.ts insider app
- create app.module.ts insider app
- update code of styles.css and main.ts
- update code of app.component.html and app.component.ts
<!-- app/stocks/stocks.component.html -->
<div class="App">
<h1>Stock Market Angular App</h1>
<h2>Stocks</h2>
<ul>
<li *ngFor="let stock of stocks" [style.color]="stock.color">
{{ stock.company }} ({{ stock.symbol }}) - ${{ stock.initial_price }}
<button
(click)="addToWatchlist(stock)"
[disabled]="stock.addedToWatchlist"
>
Add to My Watchlist
</button>
</li>
</ul>
</div>
<!-- app/watchlist/watchlist.component.html -->
<div class="App">
<h1>Stock Market Angular App</h1>
<h2>My Watchlist</h2>
<ul>
<li *ngFor="let stock of watchlist"
[style.color]="stock.color">
{{ stock.company }} ({{ stock.symbol }}) -
${{ stock.initial_price }}
</li>
</ul>
</div>
<!-- app.component.html -->
<nav>
<div class="navbar">
<button (click)="toggleView('stocks')">Stocks</button>
<button (click)="toggleView('watchlist')">Watchlist</button>
</div>
</nav>
<app-stocks *ngIf="showStocks" (addToWatchlistEvent)="addToWatchlist($event)"></app-stocks>
<app-watchlist *ngIf="!showStocks" [watchlist]="watchlist"></app-watchlist>
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stock Market MEAN App</title>
</head>
<body>
<app-root></app-root>
</body>
</html>
/* styles.css */
body {
font-family: 'Arial', sans-serif;
background-color: #d9d7ca;
margin: 0;
padding: 0;
}
.App {
text-align: center;
padding: 20px;
}
h1 {
color: #1f454d;
}
h2 {
color: #3c8d93;
margin-top: 30px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background-color: #3c8d93;
color: #d9d7ca;
padding: 10px;
margin: 10px 0;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
button {
background-color: #1f454d;
color: #d9d7ca;
border: none;
padding: 8px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #3c8d93;
}
/* Navigation bar styles */
nav {
background-color: #1f454d;
padding: 15px 0;
}
nav a {
color: #d9d7ca;
text-decoration: none;
margin: 0 20px;
font-size: 18px;
transition: color 0.3s ease;
}
nav a:hover {
color: #3c8d93;
}
//app/stocks/stocks.component.ts
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-stocks',
templateUrl: './stocks.component.html',
})
export class StocksComponent implements OnInit {
@Output() addToWatchlistEvent = new EventEmitter<any>();
stocks: any[] = [
{ company: 'Company A', symbol: 'AAA', initial_price: 97, color: '' },
{ company: 'Company B', symbol: 'BBB', initial_price: 150, color: '' },
{ company: 'Company C', symbol: 'CCC', initial_price: 10, color: '' },
{ company: 'Company D', symbol: 'DDD', initial_price: 1150, color: '' },
{ company: 'Company E', symbol: 'EEE', initial_price: 14, color: '' },
{ company: 'Company F', symbol: 'FFF', initial_price: 270, color: '' },
{ company: 'Company G', symbol: 'GGG', initial_price: 73, color: '' },
{ company: 'Company H', symbol: 'HHH', initial_price: 765, color: '' },
{ company: 'Company I', symbol: 'III', initial_price: 75, color: '' },
];
constructor() { }
ngOnInit(): void {
this.setColors();
}
addToWatchlist(stock: any) {
this.addToWatchlistEvent.emit(stock);
stock.addedToWatchlist = true;
}
setColors() {
this.stocks.forEach((stock, index) => {
stock.color = index % 2 === 0 ? '#FF0000' : '#00FF00';
});
}
}
//app/watchlist/watchlist.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-watchlist',
templateUrl: './watchlist.component.html',
})
export class WatchlistComponent {
@Input() watchlist: any[] = [];
constructor() { }
}
//app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
showStocks: boolean = true;
watchlist: any[] = [];
toggleView(view: string) {
this.showStocks = view === 'stocks';
}
addToWatchlist(stock: any) {
this.watchlist.push(stock);
}
}
//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { StocksComponent } from './stocks/stocks.component';
import { WatchlistComponent } from './watchlist/watchlist.component';
const routes: Routes = [
{ path: 'stocks', component: StocksComponent },
{ path: 'watchlist', component: WatchlistComponent },
{ path: '', redirectTo: '/stocks', pathMatch: 'full' }
];
@NgModule({
declarations: [
AppComponent,
StocksComponent,
WatchlistComponent
],
imports: [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
//main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
Start the Angular App using the following command.
ng serve
Output: