Skip to main content

Know Your Angular Part 2

Making HTTP Requests and managing different HTTP codes

Use Angular's HttpClient to make HTTP requests. Here's an example of a GET request that handles different HTTP status codes, including 202 Accepted:

Example Service:

// my-service.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

@Injectable({
providedIn: 'root',
})
export class MyService {
private apiUrl = 'https://api.example.com/data'; // Replace with your API URL

constructor(private http: HttpClient) {}

getData(): Observable<any> {
return this.http.get(this.apiUrl, { observe: 'response' }).pipe(
tap((response) => {
if (response.status === 202) {
console.log('Request accepted but processing is not complete.');
}
}),
map((response) => response.body), // Extract the response body
catchError(this.handleError) // Handle errors
);
}

private handleError(error: HttpErrorResponse): Observable<never> {
let errorMessage = 'An unknown error occurred!';
if (error.error instanceof ErrorEvent) {
// Client-side error
errorMessage = `Client-side error: ${error.error.message}`;
} else {
// Server-side error
switch (error.status) {
case 400:
errorMessage = 'Bad Request';
break;
case 401:
errorMessage = 'Unauthorized';
break;
case 403:
errorMessage = 'Forbidden';
break;
case 404:
errorMessage = 'Not Found';
break;
case 500:
errorMessage = 'Internal Server Error';
break;
case 202:
errorMessage = 'Request Accepted but not yet processed.';
break;
default:
errorMessage = `Unexpected error: ${error.status}`;
}
}
console.error(errorMessage);
return throwError(() => new Error(errorMessage));
}
}

Directives for Dynamic events

Here is an Angular directive that dynamically creates event listeners for keypress or mouseover events, cleans them up automatically, and allows dynamic configuration:


Directive Code

import { Directive, ElementRef, Input, Renderer2, OnDestroy } from '@angular/core';

@Directive({
selector: '[appDynamicEvent]'
})
export class DynamicEventDirective implements OnDestroy {
@Input() eventType: 'keypress' | 'mouseover' = 'keypress'; // Dynamic event type
@Input() callback: (event: Event) => void = () => {}; // Callback function for the event

private eventListener: () => void; // To store the event listener for cleanup

constructor(private el: ElementRef, private renderer: Renderer2) {}

ngOnInit(): void {
// Add the event listener dynamically
this.eventListener = this.renderer.listen(this.el.nativeElement, this.eventType, (event) => {
if (this.callback) {
this.callback(event); // Execute the callback function
}
});
}

ngOnDestroy(): void {
// Clean up the event listener when the directive is destroyed
if (this.eventListener) {
this.eventListener();
}
}
}

How It Works

  1. Dynamic Event Type:

    • The @Input() eventType allows you to specify the type of event (keypress or mouseover).
    • Default is set to keypress.
  2. Dynamic Callback:

    • The @Input() callback allows you to pass a custom function to handle the event.
  3. Event Listener:

    • The Renderer2.listen method is used to attach the event listener dynamically to the element.
  4. Cleanup:

    • The ngOnDestroy lifecycle hook ensures that the event listener is removed when the directive is destroyed, preventing memory leaks.

Usage Example

Template

<div
appDynamicEvent
[eventType]="'mouseover'"
[callback]="onMouseOver"
style="width: 200px; height: 100px; background-color: lightblue;"
>
Hover over me!
</div>

<input
appDynamicEvent
[eventType]="'keypress'"
[callback]="onKeyPress"
placeholder="Type something..."
/>

Component

import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
onMouseOver(event: Event): void {
console.log('Mouse over event:', event);
}

onKeyPress(event: Event): void {
console.log('Key press event:', event);
}
}

Explanation

  1. Mouseover Example:

    • When you hover over the div, the onMouseOver callback is triggered, and the event is logged to the console.
  2. Keypress Example:

    • When you type in the input field, the onKeyPress callback is triggered, and the event is logged to the console.
  3. Dynamic Behavior:

    • You can dynamically change the eventType and callback to handle different events and actions.
  4. Cleanup:

    • When the directive is destroyed (e.g., when the element is removed from the DOM), the event listener is automatically cleaned up.

Benefits

  • Dynamic: Supports multiple event types and custom callbacks.
  • Clean: Automatically removes event listeners to prevent memory leaks.
  • Reusable: Can be applied to any element with minimal configuration.