API calls – Angular

In Angular, there are several ways to make API calls using built-in services and external libraries. Here’s an overview of different approaches:

1. Using HttpClient (Built-in Angular Service)

The HttpClient service is the most common and built-in way to make HTTP requests in Angular. It is part of the @angular/common/http module and provides methods like get(), post(), put(), delete(), etc.

#### Setup:
Ensure HttpClientModule is imported in your module:

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

   @NgModule({
     imports: [HttpClientModule],
   })
   export class AppModule {}

#### Example of a GET request:

   import { HttpClient } from '@angular/common/http';
   import { Injectable } from '@angular/core';
   import { Observable } from 'rxjs';

   @Injectable({
     providedIn: 'root',
   })
   export class ApiService {
     private apiUrl = 'https://api.example.com/data';

     constructor(private http: HttpClient) {}

     getData(): Observable<any> {
       return this.http.get(this.apiUrl);
     }
   }

Use this service in a component:

   import { Component, OnInit } from '@angular/core';
   import { ApiService } from './api.service';

   @Component({
     selector: 'app-my-component',
     template: `<div *ngIf="data">{{ data | json }}</div>`,
   })
   export class MyComponent implements OnInit {
     data: any;

     constructor(private apiService: ApiService) {}

     ngOnInit(): void {
       this.apiService.getData().subscribe((response) => {
         this.data = response;
       });
     }
   }

2. Using HttpClient with Observables and RxJS

Angular’s HttpClient works well with RxJS Observables, which are powerful for handling asynchronous data streams.

#### Example of handling multiple requests with forkJoin:

   import { forkJoin } from 'rxjs';

   this.apiService.getData1().subscribe(data => console.log(data)); // Single request

   forkJoin([this.apiService.getData1(), this.apiService.getData2()]).subscribe(([data1, data2]) => {
     console.log(data1, data2);
   });

#### Example of using RxJS switchMap for sequential API calls:

   this.apiService.getData1().pipe(
     switchMap(data1 => this.apiService.getData2(data1.id))
   ).subscribe(data2 => {
     console.log(data2);
   });

3. Using HttpClient with Promise (Alternative to Observables)

You can convert Angular’s HttpClient observables into promises if preferred.

   getDataAsPromise(): Promise<any> {
     return this.http.get(this.apiUrl).toPromise();
   }

Then use it in a component like this:

   this.apiService.getDataAsPromise().then((data) => {
     console.log(data);
   }).catch((error) => {
     console.error('Error:', error);
   });

4. Using HttpClient with Interceptors (Global Request/Response Handling)

Interceptors allow you to modify requests and responses globally. They are useful for adding authorization headers, logging, or handling errors.

#### Example of an interceptor:

   import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
   import { Injectable } from '@angular/core';
   import { Observable } from 'rxjs';

   @Injectable()
   export class AuthInterceptor implements HttpInterceptor {
     intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
       const clonedReq = req.clone({
         headers: req.headers.set('Authorization', 'Bearer my-token'),
       });
       return next.handle(clonedReq);
     }
   }

You need to provide this interceptor in your module:

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

   @NgModule({
     providers: [
       { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
     ],
   })
   export class AppModule {}

5. Using HttpClient with Retry and Error Handling (RxJS Operators)

You can handle retries and errors using RxJS operators like retry, catchError, and throwError.

#### Example with retry and error handling:

   import { retry, catchError } from 'rxjs/operators';
   import { throwError } from 'rxjs';

   this.http.get(this.apiUrl).pipe(
     retry(3),  // Retry up to 3 times
     catchError((error) => {
       console.error('Error occurred:', error);
       return throwError(error);
     })
   ).subscribe(
     (data) => console.log(data),
     (error) => console.error('Error in subscribe:', error)
   );

6. Using HttpClient with async/await (Wrapping in a Promise)

If you prefer async/await syntax, you can wrap the HttpClient observable in a Promise and use it with await.

   async fetchData() {
     try {
       const data = await this.http.get(this.apiUrl).toPromise();
       console.log(data);
     } catch (error) {
       console.error('Error:', error);
     }
   }

Then, call this function in your component:

   this.fetchData();

7. Using HttpClient with Subjects for Better State Management

You can use Subject or BehaviorSubject for sharing API data between components.

#### Example with BehaviorSubject:

   import { BehaviorSubject, Observable } from 'rxjs';

   private dataSubject = new BehaviorSubject<any>(null);

   getData(): Observable<any> {
     return this.dataSubject.asObservable();
   }

   fetchData() {
     this.http.get(this.apiUrl).subscribe((data) => {
       this.dataSubject.next(data);
     });
   }

Use this in components to subscribe to the shared data stream.

8. Using External Libraries like axios

Although Angular has built-in HTTP services, you can still use external libraries like axios.

First, install axios:

   npm install axios

Then use it in your service:

   import axios from 'axios';

   getData() {
     return axios.get('https://api.example.com/data').then((response) => {
       return response.data;
     });
   }

Use this service in your component similarly as shown above.

9. Using Apollo for GraphQL API Calls

If you’re working with GraphQL APIs, you can use Apollo for managing GraphQL queries in Angular.

Install Apollo:

   ng add apollo-angular

Then use it in your component:

   import { Apollo } from 'apollo-angular';
   import gql from 'graphql-tag';

   this.apollo
     .watchQuery({
       query: gql`
         {
           getData {
             id
             name
           }
         }
       `,
     })
     .valueChanges.subscribe((result: any) => {
       this.data = result?.data?.getData;
     });

10. Using NgRx (For State Management)

You can use NgRx to manage API calls with a more structured approach using Redux-like state management.

In effects.ts:

   loadData$ = createEffect(() =>
     this.actions$.pipe(
       ofType(loadData),
       switchMap(() =>
         this.apiService.getData().pipe(
           map((data) => loadDataSuccess({ data })),
           catchError((error) => of(loadDataFailure({ error })))
         )
       )
     )
   );

These are various ways to handle API calls in Angular, each serving different use cases based on the project requirements. HttpClient is the core service for most API operations, while RxJS operators, interceptors, and external libraries can further enhance API handling.

Tags: No tags

Add a Comment

Your email address will not be published. Required fields are marked *