Contents
Hi there, today we will show you how to develop login and registration in Angular 17 app using API. Most of the web apps today that have users or different types of users require login or authentication to safeguard the functionalities and data information of the system. And today, I will show you how to make a user login and registration in Angular 17.
Angular is a popular open-source front-end web application framework primarily maintained by Google and a community of developers. It’s used for building dynamic, single-page web applications (SPAs) and provides tools and architecture to streamline the development process. Angular enables developers to create rich, interactive, and responsive user interfaces.
In this tutorial, we will be using the REST API available that is made by Binaryboxtus. you can check it out here.
Prerequisite:
- ^18.13.0 || ^20.9.0
- @angular/cli
Step 1: Create An Angular 17 Project
First, select a folder that you want the Angular 17 project to be created then execute this command on Terminal or CMD :
ng new angular-login-register --routing --no-standalone
Step 2: Install packages
After creating a fresh angular project, go to the vue.js project folder and install these packages:
- bootstrap – a package of bootstrap framework
- axios – a promised-based HTTP library that is used to request to a server or API.
npm i bootstrap
npm i axios
After installing the packages. import the bootstrap in style.css.
src\styles.css
/* You can add global styles to this file, and also import other style files */
@import "~bootstrap/dist/css/bootstrap.css";
Step 3: Configure Application Environment
After installing the packages, we will now generate the app environment. We will declare the API base URL and API Key. Run the command below:
ng generate environments
You can get the API_KEY here. Click the “Reveal Key” button and copy the API key.
After running the command this will generate files for the environment. let’s add value to the environment.
environment.development.ts
export const environment = {
production: false,
apiUrl: 'https://mock-api.binaryboxtuts.com/',
apiKey: 'insert_api_key_here'
};
After configuring the environment, let’s configure the axios on main.ts.
src\main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import axios from 'axios';
import { environment } from './environments/environment.development';
axios.defaults.baseURL = environment.apiUrl
axios.interceptors.request.use(function (config) {
config.headers['X-Binarybox-Api-Key'] = environment.apiKey
return config;
});
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
Step 4: Create Components
We will now create the components. run the command below:
ng generate component login
ng generate component register
ng generate component dashboard
after running these commands it will create folders with files in them. We will now update the code on it.
src\app\login\login.component.ts
import { Component, OnInit } from '@angular/core';
import { UserAuthService } from '../user-auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit{
email:string = ''
password:string = ''
isSubmitting:boolean = false
validationErrors:Array<any> = []
constructor(public userAuthService: UserAuthService, private router: Router) {}
ngOnInit(): void {
if(localStorage.getItem('token') != "" && localStorage.getItem('token') != null){
this.router.navigateByUrl('/dashboard')
}
}
loginAction() {
this.isSubmitting = true;
let payload = {
email:this.email,
password: this.password,
}
this.userAuthService.login(payload)
.then(({data}) => {
localStorage.setItem('token', data.token)
this.router.navigateByUrl('/dashboard')
return data
}).catch(error => {
this.isSubmitting = false;
if (error.response.data.errors != undefined) {
this.validationErrors = error.response.data.message
}
if (error.response.data.error != undefined) {
this.validationErrors = error.response.data.error
}
return error
})
}
}
src\app\login\login.component.html
<div class="row justify-content-md-center mt-5">
<div class="col-4">
<div class="card">
<div class="card-body">
<h5 class="card-title mb-4">Sign In</h5>
<form >
<p *ngIf="validationErrors.length > 0" class='text-center '>
<small class='text-danger'>{{validationErrors}}</small>
</p>
<div class="mb-3">
<label
for="email"
class="form-label">
Email address
</label>
<input
type="email"
class="form-control"
id="email"
name="email"
required
[(ngModel)]="email"
/>
</div>
<div class="mb-3">
<label
for="password"
class="form-label">Password
</label>
<input
type="password"
class="form-control"
id="password"
name="password"
required
[(ngModel)]="password"
/>
</div>
<div class="d-grid gap-2">
<button
[disabled]="isSubmitting || (password.length <= 0 || email.length <= 0)"
(click)="loginAction()"
type="button"
class="btn btn-primary btn-block">Login</button>
<p class="text-center">Don't have account? <a routerLink="/register">Register here</a></p>
</div>
</form>
</div>
</div>
</div>
</div>
src\app\register\register.component.ts
import { Component, OnInit } from '@angular/core';
import { UserAuthService } from '../user-auth.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit{
name:string = ''
email:string = ''
password:string = ''
confirmPassword:string = ''
isSubmitting:boolean = false
validationErrors:any = []
constructor(public userAuthService: UserAuthService, private router: Router) {}
ngOnInit(): void {
if(localStorage.getItem('token') != "" && localStorage.getItem('token') != null){
this.router.navigateByUrl('/dashboard')
}
}
registerAction() {
this.isSubmitting = true;
let payload = {
name:this.name,
email:this.email,
password:this.password,
confirmPassword:this.confirmPassword
}
this.userAuthService.register(payload)
.then(({data}) => {
localStorage.setItem('token', data.token)
this.router.navigateByUrl('/dashboard')
return data
}).catch(error => {
this.isSubmitting = false;
if (error.response.data.errors != undefined) {
this.validationErrors = error.response.data.errors
}
return error
})
}
}
src\app\register\register.component.html
<div class="row justify-content-md-center mt-5">
<div class="col-4">
<div class="card">
<div class="card-body">
<h5 class="card-title mb-4">Register</h5>
<form >
<div class="mb-3">
<label
for="name"
class="form-label">Name
</label>
<input
type="text"
class="form-control"
id="name"
name="name"
[(ngModel)]="name"
/>
<div *ngIf="validationErrors?.name != undefined" class="flex flex-col">
<small class="text-danger">
{{validationErrors.name[0]}}
</small >
</div>
</div>
<div class="mb-3">
<label
for="email"
class="form-label">
Email address
</label>
<input
type="email"
class="form-control"
id="email"
name="email"
required
[(ngModel)]="email"
/>
<div *ngIf="validationErrors?.email != undefined" class="flex flex-col">
<small class="text-danger">
{{validationErrors.email[0]}}
</small >
</div>
</div>
<div class="mb-3">
<label
for="password"
class="form-label">Password
</label>
<input
type="password"
class="form-control"
id="password"
name="password"
required
[(ngModel)]="password"
/>
<div *ngIf="validationErrors?.password != undefined" class="flex flex-col">
<small class="text-danger">
{{validationErrors.password[0]}}
</small >
</div>
</div>
<div class="mb-3">
<label
for="confirm-password"
class="form-label">Confirm Password
</label>
<input
type="password"
class="form-control"
id="confirm-password"
name="confirm-password"
required
[(ngModel)]="confirmPassword"
/>
</div>
<div class="d-grid gap-2">
<button
[disabled]="isSubmitting || (password.length <= 0 || email.length <= 0 || confirmPassword.length <= 0)"
(click)="registerAction()"
type="button"
class="btn btn-primary btn-block">Register Now</button>
<p className="text-center">Have already an account <a routerLink="/login">Login here</a>
</p>
</div>
</form>
</div>
</div>
</div>
</div>
src\app\dashboard\dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { UserAuthService } from '../user-auth.service';
import { Router } from '@angular/router';
import { User } from '../user/user';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit{
user!:User
constructor(public userAuthService: UserAuthService, private router: Router) {}
ngOnInit(): void {
if(localStorage.getItem('token') == "" || localStorage.getItem('token') == null){
this.router.navigateByUrl('/')
}else {
this.userAuthService.getUser().then(({data})=>{
this.user = data;
})
}
}
logoutAction () {
this.userAuthService.logout().then(()=>{
localStorage.setItem('token', "")
this.router.navigateByUrl('/')
}).catch(()=>{
localStorage.setItem('token', "")
this.router.navigateByUrl('/')
})
}
}
src\app\dashboard\dashboard.component.html
<div class="row justify-content-md-center">
<div class="col-12">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Dashboard</a>
<div class="d-flex">
<ul class="navbar-nav">
<li class="nav-item">
<span (click)="logoutAction()" class="nav-link" aria-current="page" style="cursor: pointer;">Logout</span>
</li>
</ul>
</div>
</div>
</nav>
<h2 class="text-center mt-5">Welcome, {{user?.name}}!</h2 >
</div>
</div>
Step 5: Create Service and Interface
We will now create the service and interface
ng generate service user-auth
ng generate interface user/user
Let’s update the code of service and interface.
src/app/user-auth.service.ts
import { Injectable } from '@angular/core';
import axios from 'axios';
@Injectable({
providedIn: 'root'
})
export class UserAuthService {
constructor() { }
login(data:any): Promise<any>{
let payload = {
email: data.email,
password: data.password
}
return axios.post('/api/login', payload)
}
register(data:any): Promise<any>{
let payload = {
name: data.name,
email: data.email,
password: data.password,
password_confirmation: data.confirmPassword
}
return axios.post('/api/register', payload)
}
getUser(): Promise<any>{
return axios.get('/api/user', { headers:{Authorization: 'Bearer ' + localStorage.getItem('token')}})
}
logout(): Promise<any>{
return axios.post('/api/logout',{}, { headers:{Authorization: 'Bearer ' + localStorage.getItem('token')}})
}
}
src/app/user/user.ts
export interface User {
id: number;
name: string;
email: string;
}
Step 6: Update the AppModule and AppComponent
After creating the component we will then update the code for the module and routing:
src\app\app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { DashboardComponent } from './dashboard/dashboard.component';
@NgModule({
declarations: [
AppComponent,
LoginComponent,
RegisterComponent,
DashboardComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
import { DashboardComponent } from './dashboard/dashboard.component';
const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full'},
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'dashboard', component: DashboardComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
src\app\app.component.html
<div class="container">
<router-outlet></router-outlet>
</div>
Step 7: Run the app
We’re all done, what is left is to run the app.
ng serve
Open this URL:
http://localhost:4200/
Screenshots:
Login Page
Register Page
Dashboard Page