Angular Toast
Angular Toast:
1. Using Angular Material for Modals (Popups)
Let's first show how to create a popup (modal) to
confirm or display messages related to the CRUD operations.
Install Angular Material
First, make sure you have Angular Material installed:
ng add @angular/material
Then, choose a theme (e.g., Indigo/Pink), and add Animations
if prompted.
Next, import the necessary Angular Material modules into
your app.module.ts:
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from
'@angular/platform-browser/animations';
import { MatDialogModule } from '@angular/material/dialog';
// Import MatDialog
import { MatButtonModule } from '@angular/material/button';
// Import MatButton
import { AppComponent } from './app.component';
import { CrudComponent } from './crud/crud.component';
import { DeleteConfirmDialogComponent } from
'./delete-confirm-dialog/delete-confirm-dialog.component'; // Add the dialog
component
@NgModule({
declarations: [
AppComponent,
CrudComponent,
DeleteConfirmDialogComponent // Declare the dialog component
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
BrowserAnimationsModule,
MatDialogModule,
// Add to imports
MatButtonModule //
Add button module
],
providers: [],
bootstrap:
[AppComponent],
entryComponents:
[DeleteConfirmDialogComponent] // Declare the dialog component as entry
component
})
export class AppModule { }
Create a Confirmation Dialog for Deleting Items
Create a new component for the delete confirmation dialog:
ng generate component delete-confirm-dialog
Edit delete-confirm-dialog.component.ts to display a
confirmation message:
// delete-confirm-dialog.component.ts
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
@Component({
selector:
'app-delete-confirm-dialog',
templateUrl:
'./delete-confirm-dialog.component.html',
styleUrls:
['./delete-confirm-dialog.component.css']
})
export class DeleteConfirmDialogComponent {
constructor(public
dialogRef: MatDialogRef<DeleteConfirmDialogComponent>) {}
onConfirm(): void {
this.dialogRef.close(true); // Close the dialog and return true
}
onCancel(): void {
this.dialogRef.close(false); // Close the dialog and return false
}
}
Create the template for the dialog (delete-confirm-dialog.component.html):
<!-- delete-confirm-dialog.component.html -->
<h2 mat-dialog-title>Confirm Deletion</h2>
<mat-dialog-content>
Are you sure you
want to delete this item?
</mat-dialog-content>
<mat-dialog-actions>
<button
mat-button (click)="onCancel()">Cancel</button>
<button
mat-button color="warn"
(click)="onConfirm()">Delete</button>
</mat-dialog-actions>
Use the Dialog in CRUD Component
Now, in your CRUD Component, use the dialog to
confirm deletions:
// crud.component.ts
import { Component, OnInit } from '@angular/core';
import { CrudService } from './crud.service';
import { MatDialog } from '@angular/material/dialog';
import { DeleteConfirmDialogComponent } from
'./delete-confirm-dialog/delete-confirm-dialog.component';
import { catchError, of } from 'rxjs';
@Component({
selector:
'app-crud',
templateUrl:
'./crud.component.html',
styleUrls:
['./crud.component.css']
})
export class CrudComponent implements OnInit {
items: any[] = [];
currentItem: any = {
id: 0, name: '' }; // Example object
errorMessage: string
= '';
constructor(private
crudService: CrudService, private dialog: MatDialog) {}
ngOnInit(): void {
this.loadItems();
}
loadItems(): void {
this.crudService.getItems().pipe(
catchError(err
=> {
this.errorMessage = 'Failed to load items';
return of([]);
// Return empty array on error
})
).subscribe(
(data: any[])
=> {
this.items =
data;
},
error => {
console.error('Error loading items', error);
}
);
}
createItem(): void {
this.crudService.createItem(this.currentItem).pipe(
catchError(err
=> {
this.errorMessage = 'Failed to create item';
return
of(null); // Return null on error
})
).subscribe(
(data) => {
if (data) {
this.items.push(data); // Add the newly created item to the list
this.resetForm();
}
},
error => {
console.error('Error creating item', error);
}
);
}
updateItem(): void {
this.crudService.updateItem(this.currentItem.id,
this.currentItem).pipe(
catchError(err
=> {
this.errorMessage = 'Failed to update item';
return
of(null); // Return null on error
})
).subscribe(
(data) => {
if (data) {
const index
= this.items.findIndex(item => item.id === data.id);
if (index
!== -1) {
this.items[index] = data; // Update the item in the list
}
this.resetForm();
}
},
error => {
console.error('Error updating item', error);
}
);
}
deleteItem(id:
number): void {
const dialogRef =
this.dialog.open(DeleteConfirmDialogComponent);
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.crudService.deleteItem(id).pipe(
catchError(err => {
this.errorMessage = 'Failed to delete item';
return
of(null); // Return null on error
})
).subscribe(
() => {
this.items
= this.items.filter(item => item.id !== id); // Remove the item from the
list
},
error =>
{
console.error('Error deleting item', error);
}
);
}
});
}
resetForm(): void {
this.currentItem =
{ id: 0, name: '' }; // Reset form fields
}
editItem(item: any):
void {
this.currentItem =
{ ...item }; // Set the form with the current item's data
}
}
2. Using ngx-toastr for Toast Notifications
To show toast notifications for successful CRUD operations
or errors, you can use the ngx-toastr library.
Install ngx-toastr
npm install ngx-toastr
npm install @angular/animations
Import ngx-toastr Modules
Import the necessary modules into app.module.ts:
// app.module.ts
import { ToastrModule } from 'ngx-toastr';
import { BrowserAnimationsModule } from
'@angular/platform-browser/animations';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
BrowserAnimationsModule,
ToastrModule.forRoot() // Add ToastrModule
]
})
export class AppModule { }
Using Toastr in CRUD Operations
Now, in the CRUD Component, you can inject and use ToastrService
to show success or error toasts.
// crud.component.ts
import { Component, OnInit } from '@angular/core';
import { CrudService } from './crud.service';
import { ToastrService } from 'ngx-toastr'; // Import
ToastrService
import { catchError, of } from 'rxjs';
@Component({
selector:
'app-crud',
templateUrl:
'./crud.component.html',
styleUrls:
['./crud.component.css']
})
export class CrudComponent implements OnInit {
items: any[] = [];
currentItem: any = {
id: 0, name: '' }; // Example object
errorMessage: string
= '';
constructor(
private
crudService: CrudService,
private toastr:
ToastrService // Inject ToastrService
) {}
ngOnInit(): void {
this.loadItems();
}
loadItems(): void {
this.crudService.getItems().pipe(
catchError(err
=> {
this.toastr.error('Failed to load items', 'Error'); // Toast error
return of([]);
// Return empty array on error
})
).subscribe(
(data: any[])
=> {
this.items =
data;
}
);
}
createItem(): void {
this.crudService.createItem(this.currentItem).pipe(
catchError(err
=> {
this.toastr.error('Failed to create item', 'Error'); // Toast error
return
of(null); // Return null on error
})
).subscribe(
(data) => {
if (data) {
this.items.push(data); // Add the newly created item to the list
this.resetForm();
this.toastr.success('Item created successfully', 'Success'); // Toast
success
}
}
);
}
updateItem(): void {
this.crudService.updateItem(this.currentItem.id, this.currentItem).pipe(
catchError(err
=> {
this.toastr.error('Failed to update item', 'Error'); // Toast error
return
of(null); // Return null on error
})
).subscribe(
(data) => {
if (data) {
const index
= this.items.findIndex(item => item.id === data.id);
if (index
!== -1) {
this.items[index] = data; // Update the item in the list
}
this.resetForm();
this.toastr.success('Item updated successfully', 'Success'); // Toast
success
}
}
);
}
deleteItem(id:
number): void {
const dialogRef =
this.dialog.open(DeleteConfirmDialogComponent);
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.crudService.deleteItem(id).pipe(
catchError(err => {
this.toastr.error('Failed to delete item', 'Error'); // Toast error
return
of(null); // Return null on error
})
).subscribe(
() => {
this.items
= this.items.filter(item => item.id !== id); // Remove the item from the
list
this.toastr.success('Item deleted successfully', 'Success'); // Toast
success
}
);
}
});
}
resetForm(): void {
this.currentItem =
{ id: 0, name: '' }; // Reset form fields
}
editItem(item: any):
void {
this.currentItem =
{ ...item }; // Set the form with the current item's data
}
}
To build a .NET Core Web API to support your CRUD
operations, we can create a simple Web API with endpoints that handle basic
CRUD functionality for the items. Below is a simplified version of a .NET Core
Web API for your Angular CRUD operations.
Step 1: Create a .NET Core Web API Project
First, create a new .NET Core Web API project. You can do
this using the following command in the terminal or by using Visual Studio:
dotnet new webapi -n CrudApi
cd CrudApi
Step 2: Define the Model
Create a model for Item that corresponds to the data you
will be working with:
// Models/Item.cs
namespace CrudApi.Models
{
public class Item
{
public int Id
{ get; set; }
public string
Name { get; set; }
}
}
Step 3: Create the Data Context
Set up an in-memory database context for simplicity, or you
can use a real database like SQL Server.
// Data/ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using CrudApi.Models;
namespace CrudApi.Data
{
public class
ApplicationDbContext : DbContext
{
public
ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
:
base(options)
{
}
public
DbSet<Item> Items { get; set; }
}
}
Step 4: Create a Controller for CRUD Operations
Create a controller that will handle all CRUD operations
(Create, Read, Update, Delete) for the Item entity.
// Controllers/ItemsController.cs
using Microsoft.AspNetCore.Mvc;
using CrudApi.Data;
using CrudApi.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CrudApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class
ItemsController : ControllerBase
{
private
readonly ApplicationDbContext _context;
public
ItemsController(ApplicationDbContext context)
{
_context =
context;
}
// GET:
api/items
[HttpGet]
public async
Task<ActionResult<IEnumerable<Item>>> GetItems()
{
return
await _context.Items.ToListAsync();
}
// GET:
api/items/5
[HttpGet("{id}")]
public async
Task<ActionResult<Item>> GetItem(int id)
{
var item =
await _context.Items.FindAsync(id);
if (item
== null)
{
return
NotFound();
}
return
item;
}
// POST:
api/items
[HttpPost]
public async
Task<ActionResult<Item>> PostItem(Item item)
{
_context.Items.Add(item);
await
_context.SaveChangesAsync();
return
CreatedAtAction(nameof(GetItem), new { id = item.Id }, item);
}
// PUT:
api/items/5
[HttpPut("{id}")]
public async
Task<IActionResult> PutItem(int id, Item item)
{
if (id !=
item.Id)
{
return
BadRequest();
}
_context.Entry(item).State = EntityState.Modified;
await
_context.SaveChangesAsync();
return
NoContent();
}
// DELETE:
api/items/5
[HttpDelete("{id}")]
public async
Task<IActionResult> DeleteItem(int id)
{
var item =
await _context.Items.FindAsync(id);
if (item
== null)
{
return
NotFound();
}
_context.Items.Remove(item);
await
_context.SaveChangesAsync();
return
NoContent();
}
}
}
Step 5: Add Dependencies for Entity Framework Core
To work with a database in a .NET Core Web API, add the
necessary packages for Entity Framework Core:
- In
the terminal, run the following command to install the required NuGet
packages:
dotnet add package Microsoft.EntityFrameworkCore --version
7.0.0
dotnet add package Microsoft.EntityFrameworkCore.InMemory
--version 7.0.0
- Update
the Program.cs file to configure the services and database context:
// Program.cs
using CrudApi.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Add DbContext using InMemory database for simplicity
builder.Services.AddDbContext<ApplicationDbContext>(options
=>
options.UseInMemoryDatabase("ItemsDb"));
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
Step 6: Run the Application
You can run the Web API by using the following command:
dotnet run
This will start the API on https://localhost:5001 by
default. The endpoints will be:
- GET
/api/items – Get all items
- GET
/api/items/{id} – Get a single item by ID
- POST
/api/items – Create a new item
- PUT
/api/items/{id} – Update an item
- DELETE
/api/items/{id} – Delete an item
Step 7: Enable Cross-Origin Requests (CORS)
To allow your Angular frontend to interact with this Web
API, you need to enable Cross-Origin Resource Sharing (CORS). In the Program.cs
file, add the following code before app.Run():
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
app.UseCors("AllowAll");
Step 8: Test the API
Now that your API is running, you can test the CRUD
operations using tools like Postman or directly via your Angular frontend,
which we discussed in the previous section.
This API will provide the necessary endpoints for the
Angular app to perform CRUD operations on the Item model. Each endpoint matches
the expected methods in the Angular CrudService.
Summary of the Web API:
- GET
/api/items: Retrieve all items.
- GET
/api/items/{id}: Retrieve a specific item by ID.
- POST
/api/items: Create a new item.
- PUT
/api/items/{id}: Update an existing item.
- DELETE
/api/items/{id}: Delete an item.
You can now integrate this API with the Angular frontend
that uses Angular Material for the UI and ngx-toastr for notifications.
Comments
Post a Comment