• Home
  • About
    • Hanna's Blog photo

      Hanna's Blog

      I wanna be a global developer.

    • Learn More
    • Email
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

[.Net 6] Angular SuperHero

27 Sep 2022

Reading time ~6 minutes

Create the Angular Application

Create Project

  • Create Project Folder named SuperHeroNG
Create the Angular Application
  • Download Node.js
Create the Angular Application
  • Open project forder in Visual Studio Code
  • Set powershell policy with Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
  • Download Angular CLI with npm install -g @angular/cli
  • Create new angular projekt skeleton with ng new SuperHero.UI in SuperHeroNG folder
Create the Angular Application
  • Add components, models and services folders in src/app
  • Run angular with ng serve -o in SuperHero.UI folder
Create the Angular Application

Add the Super Hero Model to the Client

Download Extensions

  • Download Angular Language Service in Visual Studio Code
Add the Super Hero Model to the Client

Super Hero Model

  • SuperHero.UI/src/app/models/super-hero.ts
export class SuperHero {
    id?: number;
    name = "";
    firstName = "";
    lastName = "";
    place = "";
}

Generate an Angular Service

Service

  • Move to app\services
  • Create super-hero service with ng g s super-hero --skip-tests
Generate an Angular Service
  • SuperHero.UI/src/app/services/super-hero.service.ts
...
export class SuperHeroService {

  constructor() { }

  public getSuperHeroes() : SuperHero[] {
    let hero = new SuperHero();
    hero.id = 1;
    hero.name = "Spider Man";
    hero.firstName = "Peter";
    hero.lastName = "Parker";
    hero.place = "New York City";

    return [hero];
  }
...

Component

  • Clear app/app.component.html

  • SuperHero.UI/src/app/app.component.ts

...
export class AppComponent {
  title = 'SuperHero.UI';
  heroes: SuperHero[] = [];

  constructor(private superHeroService: SuperHeroService) {}

  ngOnInit() : void {
    this.heroes = this.superHeroService.getSuperHeroes();
    console.log(this.heroes);
  }
...

Run

  • Run with ng serve -o
Generate an Angular Service

Implement a Table to Show the Hero List

  • SuperHero.UI/src/app/app.component.html
<table>
    <thead>
        <th>Name</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Place</th>
    </thead>
    <tbody>
        <tr *ngFor="let hero of heroes">
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>
Implement a Table to Show the Hero List

Create the .Net 6 Web API Project

  • Create a ASP.NET CORE WEB API project named SuperHeroAPI on same folder with UI in Visual Studio
Implement a Table to Show the Hero List

Add the Super Hero Model to the API

  • SuperHeroAPI/SuperHero.cs
public class SuperHero
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;    
    public string FirstName { get; set; } = string.Empty;    
    public string LastName { get; set; } = string.Empty;    
    public string Place { get; set; } = string.Empty;    
}

Add the Super Hero Controller

  • SuperHeroAPI/Controller/SuperHeroController.cs
[Route("api/[controller]")]
[ApiController]
public class SuperHeroController : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<List<SuperHero>>> GetSuperHeroes()
    {
        return new List<SuperHero>
        {
            new SuperHero
            {
                Name = "Spider Man",
                FirstName = "Peter",
                LastName = "Parker",
                Place = "New York City"
            }
        };
    }
}

Call the Web API from the Angular 14 Client

  • Copy your Web API url and paste on your angular.

  • SuperHero.UI/src/environment/environment.ts

export const environment = {
  production: false,
  apiUrl: "https://localhost:7169/api"
};
  • SuperHero.UI/src/app/services/super-hero.service.ts
...
export class SuperHeroService {
  private url = "SuperHero";

  constructor(private http: HttpClient) { }

  public getSuperHeroes() : Observable<SuperHero[]> {
    return this.http.get<SuperHero[]>(`${environment.apiUrl}/${this.url}`);
  }
}
...
  • SuperHero.UI/src/app/app.module.ts
...
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  ...
  • SuperHero.UI/src/app/components/app.component.ts
...
ngOnInit() : void {
    this.superHeroService
      .getSuperHeroes()
      .subscribe((result: SuperHero[]) => (this.heroes = result));
  }
...

Enable CORS(Cross-Origin Resource Sharing)

  • SuperHero.API/Program.cs
builder.Services.AddCors(options => options.AddPolicy(name: "SuperHeroOrigins", // To Access the Origins
    policy =>
    {
        policy.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
    }));
    ...
app.UseCors("SuperHeroOrigins");
...
Enable CORS(Cross-Origin Resource Sharing)

Add Entity Framework Core 6

  • Create Data folder in SuperHeroAPI

  • SuperHero.API/Data/DataContext.cs

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {

    }

    public DbSet<SuperHero> SuperHeroes => Set<SuperHero>();
}
  • Download Microsoft.EntityFrameworkCore.Design and Microsoft.EntityFrameworkCore.SqlServer in Nuget Package manager
Add Entity Framework Core 6

Add the Connection String for the SQL Server Database

  • SuperHero.API/appsettings.json
...
"ConnectionStrings": {
    "DefaultConnection": "server=localhost\\sqlexpress;database=superherodb;trusted_connection=true"
  },
  ...

Install the EF Core Tools

  • Download Dotnet EntityCore Tools with dotnet tool install --global dotnet-ef and check with dotnet ef
Install the EF Core Tools

Register the DataContext in the Program.cs

  • SuperHero.API/Program.cs
builder.Services.AddDbContext<DataContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});

Run the Initial Migration using Code-First Migration

  • Migration data table with dotnet ef migrations add Initial
Run the Initial Migration using Code-First Migration
  • Update database with dotnet ef database update
Run the Initial Migration using Code-First Migration

Get Super Heroes from the Database

  • SuperHero.API/Controllers/SuperHeroController.cs
[Route("api/[controller]")]
[ApiController]
public class SuperHeroController : ControllerBase
{
    private readonly DataContext _context;

    public SuperHeroController(DataContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async Task<ActionResult<List<SuperHero>>> GetSuperHeroes()
    {
        return Ok(await _context.SuperHeroes.ToListAsync());
    }
}
  • Add a row in database
Run the Initial Migration using Code-First Migration

Implement Create, Update and Delete in the SuperHeroController

  • SuperHero.API/Controllers/SuperHeroController.cs
...
[HttpPost]
public async Task<ActionResult<List<SuperHero>>> CreateSuperHero(SuperHero hero) 
{
    _context.SuperHeroes.Add(hero);
    await _context.SaveChangesAsync();

    return Ok(await _context.SuperHeroes.ToListAsync());
}

[HttpPut]
public async Task<ActionResult<List<SuperHero>>> UpdateSuperHero(SuperHero hero)
{
    var dbHero = await _context.SuperHeroes.FindAsync(hero.Id);
    if (dbHero == null)
        return BadRequest("Hero not found.");

    dbHero.Name = hero.Name;
    dbHero.FirstName = hero.FirstName;
    dbHero.LastName = hero.LastName;
    dbHero.Place = hero.Place;

    await _context.SaveChangesAsync();

    return Ok(await _context.SuperHeroes.ToListAsync());
}

[HttpDelete("{id}")]
public async Task<ActionResult<List<SuperHero>>> DeleteSuperHero(int id)
{
    var dbHero = await _context.SuperHeroes.FindAsync(id);
    if (dbHero == null)
        return BadRequest("Hero not found.");

    _context.SuperHeroes.Remove(dbHero);
    await _context.SaveChangesAsync();

    return Ok(await _context.SuperHeroes.ToListAsync()); 
}
...

Build a Edit-Hero Component with Angular

  • Add a new component with ng n c edit-hero --skip-tests in app\components
Build a Edit-Hero Component with Angular
  • SuperHero.UI/src/app/components/edit-hero.component.ts
...
export class EditHeroComponent implements OnInit {
  @Input() hero?: SuperHero;
...
  updateHero(hero:SuperHero){

  }

  deleteHero(hero:SuperHero){
    
  }

  createHero(hero:SuperHero){
    
  }
  ...
  • SuperHero.UI/src/app.module.ts
...
imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule
  ],
...
  • SuperHero.UI/src/app/components/edit-hero.component.ts
<div *ngIf="hero">
    <h2></h2>
    <div>
        Name:
        <input [(ngModel)]="hero.name" placeholder="Name"/>
    </div>
    <div>
        First Name:
        <input [(ngModel)]="hero.firstName" placeholder="First Name"/>
    </div>
    <div>
        Last Name:
        <input [(ngModel)]="hero.lastName" placeholder="Last Name"/>
    </div>
    <div>
        Place:
        <input [(ngModel)]="hero.place" placeholder="Place"/>
    </div>
    <button (click)="updateHero(hero)" *ngIf="hero.id">Save</button>
    <button (click)="deleteHero(hero)" *ngIf="hero.id">Delete</button>
    <button (click)="createHero(hero)" *ngIf="!hero.id">Create</button>
</div>

Add the Edit-Hero Form to the Parent Form

  • SuperHero.UI/src/app/app.component.html
<button (click)="initNewHero()">Create New Hero</button>

<table>
    <thead>
        <th>Name</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Place</th>
    </thead>
    <tbody>
        <tr *ngFor="let hero of heroes">
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td><button (click)="editHero(hero)">Edit</button></td>
        </tr>
    </tbody>
</table>

<app-edit-hero [hero]="heroToEdit"></app-edit-hero>
  • SuperHero.UI/src/app/app.component.ts
export class AppComponent {
  title = 'SuperHero.UI';
  heroes: SuperHero[] = [];
  heroToEdit?: SuperHero;

  constructor(private superHeroService: SuperHeroService) {}

  ngOnInit() : void {
    this.superHeroService
      .getSuperHeroes()
      .subscribe((result: SuperHero[]) => (this.heroes = result));
  }

  initNewHero(){
    this.heroToEdit = new SuperHero();
  }

  editHero(hero: SuperHero){
    this.heroToEdit = hero;
  }
}
Add the Edit-Hero Form to the Parent Form

Implement Web Service Calls on the client

  • SuperHero.UI/src/app/services/super-hero.service.ts
export class SuperHeroService {
  private url = "SuperHero";

  constructor(private http: HttpClient) { }

  public getSuperHeroes() : Observable<SuperHero[]> {
    return this.http.get<SuperHero[]>(`${environment.apiUrl}/${this.url}`);
  }

  public upgradeHero(hero: SuperHero) : Observable<SuperHero[]> {
    return this.http.put<SuperHero[]>(`${environment.apiUrl}/${this.url}`, hero);
  }

  public createHero(hero: SuperHero) : Observable<SuperHero[]> {
    return this.http.post<SuperHero[]>(`${environment.apiUrl}/${this.url}`, hero);
  }

  public deleteHero(hero: SuperHero) : Observable<SuperHero[]> {
    return this.http.delete<SuperHero[]>(`${environment.apiUrl}/${this.url}/${hero.id}`);
  }
}

Call the Service in the EditHero Component

  • SuperHero.UI/src/app/components/edit-hero.component.ts
export class EditHeroComponent implements OnInit {
  @Input() hero?: SuperHero;
  @Output() heroesUpdated = new EventEmitter<SuperHero[]>();

  constructor(private superHeroService: SuperHeroService) { }

  ngOnInit(): void {}

  updateHero(hero:SuperHero){
    this.superHeroService.upgradeHero(hero).subscribe((heroes: SuperHero[]) => this.heroesUpdated.emit(heroes));
  }

  deleteHero(hero:SuperHero){
    this.superHeroService.deleteHero(hero).subscribe((heroes: SuperHero[]) => this.heroesUpdated.emit(heroes));
  }

  createHero(hero:SuperHero){
    this.superHeroService.createHero(hero).subscribe((heroes: SuperHero[]) => this.heroesUpdated.emit(heroes));
  }
}

Update the Super Hero Table

  • SuperHero.UI/src/app/app.component.ts
export class AppComponent {
  ...
  updateHeroList(heroes: SuperHero[]){
    this.heroes = heroes;
  }
  ...
  • SuperHero.UI/src/app/app.component.html
...
<app-edit-hero [hero]="heroToEdit" (heroesUpdated)="updateHeroList($event)"></app-edit-hero>

UI

Read

UI

Create

UI

Update

UI

Delete

UI

Download



C#.Net6AngularWebAPI Share Tweet +1