#angular #http #services #api #crud

Day 5 β€” HTTP, Services, REST APIs, CRUD & Signals

πŸ“˜ Day 5 β€” HTTP, Services, REST APIs, CRUD & Signals

Zero to Hero β€” Hands-on Angular Tutorial

Today you will learn:

  • βœ”οΈ HttpClient
  • βœ”οΈ Angular Services using inject()
  • βœ”οΈ GET / POST / PUT / DELETE
  • βœ”οΈ Error handling
  • βœ”οΈ Signals + async requests
  • βœ”οΈ Build a REAL mini CRUD app (Users API)
  • βœ”οΈ Loading & error states
  • βœ”οΈ Reusable API service patterns (enterprise level)

This day transforms you into a real-world Angular developer. πŸš€


🟦 1. Enable HttpClient in Standalone Angular

Open app.config.ts (Angular 17+) or main.ts (Angular 20).

Add:

import { provideHttpClient } from '@angular/common/http';

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient()
  ]
});
  • βœ”οΈ You just enabled HTTP for the entire app.
  • No modules needed. Modern Angular! πŸ’‘

🟩 2. Create Your First Angular API Service

Angular services = reusable logic (API calls, state management, business rules).

Generate a service:

ng g service services/users

Now open: users.service.ts

import { inject, Injectable, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root',
})
export class UsersService {
  http = inject(HttpClient);

  apiUrl = 'https://jsonplaceholder.typicode.com/users';

  users = signal<any[]>([]);
  loading = signal(false);
  error = signal('');

  loadUsers() {
    this.loading.set(true);
    this.error.set('');

    this.http.get<any[]>(this.apiUrl).subscribe({
      next: (data) => {
        this.users.set(data);
        this.loading.set(false);
      },
      error: (err) => {
        this.error.set('Failed to load users');
        this.loading.set(false);
      },
    });
  }
}

βœ”οΈ You now have:

  • signal-based state
  • loading state
  • error state
  • API integration
  • standalone Angular service

🟧 3. Display Users in a Component

Generate component:

ng g component pages/users --standalone

Open: users.component.ts

import { Component, inject, OnInit } from '@angular/core';
import { UsersService } from '../../services/users.service';
import { NgFor, NgIf } from '@angular/common';

@Component({
  selector: 'app-users',
  standalone: true,
  templateUrl: './users.component.html',
  imports: [NgIf, NgFor],
})
export class UsersComponent implements OnInit {
  service = inject(UsersService);

  ngOnInit() {
    this.service.loadUsers();
  }
}

users.component.html

<h2>Users List</h2>

<div *ngIf="service.loading()">Loading...</div>
<div *ngIf="service.error()">{{ service.error() }}</div>

<ul *ngIf="!service.loading()">
  <li *ngFor="let u of service.users()">
    {{ u.name }} β€” {{ u.email }}
  </li>
</ul>
  • βœ”οΈ Fully reactive UI
  • βœ”οΈ API-driven
  • βœ”οΈ Error + loading support

This is how enterprise Angular apps are built.


πŸŸ₯ 4. Add Route for Users Page

In app.routes.ts:

{
  path: 'users',
  loadComponent: () =>
    import('./pages/users/users.component').then(m => m.UsersComponent)
}

Add link in nav:

<a routerLink="users">Users</a>

🟫 5. Create User Detail Page

Generate:

ng g component pages/user --standalone

user.component.ts

import { Component, inject, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { UsersService } from '../../services/users.service';
import { NgIf } from '@angular/common';

@Component({
  selector: 'app-user',
  standalone: true,
  imports: [NgIf],
  templateUrl: './user.component.html',
})
export class UserComponent implements OnInit {
  route = inject(ActivatedRoute);
  service = inject(UsersService);

  user: any = null;

  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');

    this.service.http
      .get(`https://jsonplaceholder.typicode.com/users/${id}`)
      .subscribe((u) => (this.user = u));
  }
}

user.component.html

<div *ngIf="user">
  <h2>{{ user.name }}</h2>
  <p>Email: {{ user.email }}</p>
  <p>Phone: {{ user.phone }}</p>
</div>

Add route:

app.routes.ts

{
  path: 'users/:id',
  loadComponent: () =>
    import('./pages/user/user.component').then(m => m.UserComponent)
}
  • βœ”οΈ You now have Users List β†’ User Details
  • βœ”οΈ Real-world CRUD structure

🟦 6. POST Request (Create User)

Add method to the service:

createUser(user: any) {
  return this.http.post(this.apiUrl, user);
}

Usage in component:

this.service.createUser({
  name: 'New User',
  email: 'new@example.com',
}).subscribe({
  next: res => console.log('User created', res)
});

🟩 7. PUT/PATCH Request (Update User)

updateUser(id: number, data: any) {
  return this.http.put(`${this.apiUrl}/${id}`, data);
}

Usage:

this.service.updateUser(1, { name: 'Updated Name' }).subscribe();

πŸŸ₯ 8. DELETE Request

deleteUser(id: number) {
  return this.http.delete(`${this.apiUrl}/${id}`);
}

Usage:

this.service.deleteUser(1).subscribe();

🟧 9. Error Handling (Enterprise Pattern)

Modify the error callback:

error: (err) => {
  this.error.set(err.message || 'Something went wrong');
}

In template:

<div *ngIf="service.error()" class="error">
  {{ service.error() }}
</div>

🟫 10. Loading State Pattern (Signals)

Signals make this perfect:

Service:

loading = signal(false);

Template:

<div *ngIf="service.loading()">Loading...</div>
  • βœ”οΈ Clean
  • βœ”οΈ Reactive
  • βœ”οΈ Zero change detection issues
  • βœ”οΈ No RxJS required

πŸŽ‰ End of Day 5 β€” What You Accomplished

Today you learned:

  • βœ”οΈ HttpClient setup
  • βœ”οΈ GET / POST / PUT / DELETE
  • βœ”οΈ Building API Services
  • βœ”οΈ Using inject()
  • βœ”οΈ Signal-based UI state
  • βœ”οΈ Loading & error handling
  • βœ”οΈ Route-based data fetching
  • βœ”οΈ Real CRUD flows
  • βœ”οΈ Enterprise patterns

This was a big day. You’re now performing real backend communication in Angular. πŸ’ͺ


πŸ§ͺ Day 5 Challenge

Build:

πŸ‘‰ A β€œProduct Manager” mini-app

Features:

  1. /products β†’ list from API
  2. Add new product
  3. Edit product
  4. Delete product

Use:

  • HttpClient
  • Services
  • Signals
  • Error + loading states
  • Reusable API service pattern