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:

  1. 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

  1. 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

Popular posts from this blog

Multiline to singleline IN C# - CODING

EF Core interview questions for beginners

EF Core interview questions for experienced