Skip to content

Commit

Permalink
fix handler
Browse files Browse the repository at this point in the history
  • Loading branch information
vojvodicn23 committed Sep 16, 2024
1 parent 240005e commit 5fd944d
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 71 deletions.
67 changes: 55 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class AppComponent implements OnInit {
this.loading = loading;
console.log(loading);
},
[], // OPTIONAL - custom fallback value
(error) => { // OPTIONAL - custom error handler
console.log(error);
},
Expand All @@ -64,20 +65,10 @@ export class AppComponent implements OnInit {
}
```

## Fallback Response Behavior

The `handle` function guarantees that a fallback response will always be returned in case of an error, based on the type of the response (`T`).

- **If the expected response is an array type (e.g., `string[]`, `any[]`)**, the fallback will be an empty array (`[]`).
- **If the expected response is any other type (e.g., `string`, `number`, `object`)**, the fallback will be `null`.

This ensures that the `dataSetter` will always receive a value of type `T` even in the case of an error, simplifying error handling and avoiding undefined values in your application.


## API

The handle function manages HTTP requests with loading state, error handling and retry.

The `handle` function manages HTTP requests with loading state, error handling and retry.
Parameters:

- dataSetter: (response: T) => void
Expand All @@ -86,6 +77,9 @@ Function to set the data when the request succeeds (e.g., this.data = response).
- loadingSetter?: (loading: boolean) => void
Function to set the loading state (e.g., this.loading = loading).

- fallbackValue?: any
Value that will be returned in case of error.

- errorHandler?: (error: HttpErrorResponse) => void
Optional function to handle errors (e.g., console.error(error)).

Expand All @@ -96,4 +90,53 @@ Number of retries for failed requests. Defaults to 0.
Delay between retries in milliseconds.

- Returns
An Observable<T> that handles the request, error, retry.
An Observable<T> that handles the request, error, retry.


The `setDefaultErrorHandler` set default error handler for every handler request. In case custom error handler is passed as a parameter to handle function it will overwrite the default one.
Use it on root component on init method:
```typescript
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { setDefaultErrorHandler } from 'angular-http-handler';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
ngOnInit(): void {
setDefaultErrorHandler((error: HttpErrorResponse) => {
console.log('deafult handler', error);
customErrorHandlerFuction(error);
});
}
}
```


The `defaultRetryCount` and `setDefaultRetryDelay` set default number of retry in case of error and time between the calls. If you pass it as a parameter it will overwrite the default value.
Use it on root component on init method:
```typescript
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { setDefaultRetryCount, setDefaultRetryDelay } from 'angular-http-handler';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
ngOnInit(): void {
setDefaultRetryCount(2);
setDefaultRetryDelay(500);
}
}
```


## Fallback Response Behavior

The `handle` function returns a fallback response in case you define it as a 3rd parameter. In case you do not define it it will remain undefined and it will not trigger dataSetter function.
67 changes: 55 additions & 12 deletions projects/angular-http-handler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class AppComponent implements OnInit {
this.loading = loading;
console.log(loading);
},
[], // OPTIONAL - custom fallback value
(error) => { // OPTIONAL - custom error handler
console.log(error);
},
Expand All @@ -64,20 +65,10 @@ export class AppComponent implements OnInit {
}
```

## Fallback Response Behavior

The `handle` function guarantees that a fallback response will always be returned in case of an error, based on the type of the response (`T`).

- **If the expected response is an array type (e.g., `string[]`, `any[]`)**, the fallback will be an empty array (`[]`).
- **If the expected response is any other type (e.g., `string`, `number`, `object`)**, the fallback will be `null`.

This ensures that the `dataSetter` will always receive a value of type `T` even in the case of an error, simplifying error handling and avoiding undefined values in your application.


## API

The handle function manages HTTP requests with loading state, error handling and retry.

The `handle` function manages HTTP requests with loading state, error handling and retry.
Parameters:

- dataSetter: (response: T) => void
Expand All @@ -86,6 +77,9 @@ Function to set the data when the request succeeds (e.g., this.data = response).
- loadingSetter?: (loading: boolean) => void
Function to set the loading state (e.g., this.loading = loading).

- fallbackValue?: any
Value that will be returned in case of error.

- errorHandler?: (error: HttpErrorResponse) => void
Optional function to handle errors (e.g., console.error(error)).

Expand All @@ -96,4 +90,53 @@ Number of retries for failed requests. Defaults to 0.
Delay between retries in milliseconds.

- Returns
An Observable<T> that handles the request, error, retry.
An Observable<T> that handles the request, error, retry.


The `setDefaultErrorHandler` set default error handler for every handler request. In case custom error handler is passed as a parameter to handle function it will overwrite the default one.
Use it on root component on init method:
```typescript
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { setDefaultErrorHandler } from 'angular-http-handler';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
ngOnInit(): void {
setDefaultErrorHandler((error: HttpErrorResponse) => {
console.log('deafult handler', error);
customErrorHandlerFuction(error);
});
}
}
```


The `defaultRetryCount` and `setDefaultRetryDelay` set default number of retry in case of error and time between the calls. If you pass it as a parameter it will overwrite the default value.
Use it on root component on init method:
```typescript
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { setDefaultRetryCount, setDefaultRetryDelay } from 'angular-http-handler';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
ngOnInit(): void {
setDefaultRetryCount(2);
setDefaultRetryDelay(500);
}
}
```


## Fallback Response Behavior

The `handle` function returns a fallback response in case you define it as a 3rd parameter. In case you do not define it it will remain undefined and it will not trigger dataSetter function.
2 changes: 1 addition & 1 deletion projects/angular-http-handler/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-http-handler",
"version": "0.0.2",
"version": "1.0.0",
"description": "This is the http handler utility for Angular http requests",
"keywords": ["http", "angular", "loading", "error-handler"],
"author": {
Expand Down
70 changes: 44 additions & 26 deletions projects/angular-http-handler/src/lib/http-handler.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,64 @@
import { HttpErrorResponse } from "@angular/common/http";
import { catchError, finalize, Observable, of, retry, tap } from "rxjs";

let defaultErrorHandler: ((error: HttpErrorResponse) => void) | undefined;
export function setDefaultErrorHandler(handler: (error: HttpErrorResponse) => void) {
defaultErrorHandler = handler;
}

let defaultRetryCount: number = 0;
export function setDefaultRetryCount(count: number) {
defaultRetryCount = count;
}

let defaultRetryDelay: number = 0;
export function setDefaultRetryDelay(delay: number) {
defaultRetryDelay = delay;
}

export function handle<T>(
dataSetter: (response: T) => void,
loadingSetter?: (loading: boolean) => void,
fallbackValue?: any,
errorHandler?: (error: HttpErrorResponse) => void,
retryCount: number = 0,
retryDelay?: number,
retryCount: number = defaultRetryCount,
retryDelay: number = defaultRetryDelay,
): (source$: Observable<T>) => Observable<T> {
return (source$: Observable<T>) =>
source$.pipe(
tap(() => {
if(loadingSetter){
loadingSetter(true);
}
}),
return (source$: Observable<T>) => {
if(loadingSetter){
loadingSetter(true);
}
return source$.pipe(

retry({
count: retryCount,
delay: retryDelay,
resetOnSuccess: true
}),

tap((data: T) => dataSetter(data)),
catchError((error) => {
/* const errorMsg = error.error instanceof ErrorEvent
? `Error: ${error.error.message}` // Client-side error
: `Error Code: ${error.status}, Message: ${error.message}`; // Server-side error
console.error(errorMsg); */

// Call the provided error handler if it exists
if (errorHandler) {
errorHandler(error);
}

const fallback = (Array.isArray([] as unknown as T) ? [] : null) as T;

dataSetter(fallback);
return of(fallback);

catchError((error: HttpErrorResponse, caught: Observable<T>) => {
if (errorHandler) {
errorHandler(error);
} else if (defaultErrorHandler) {
defaultErrorHandler(error);
}

if(fallbackValue !== undefined){
dataSetter(fallbackValue as T);
return of(fallbackValue as T);
}
return of(null as T);
}),

finalize(() => {
if(loadingSetter){
loadingSetter(false);
}
})
);
}

);
}
}

6 changes: 6 additions & 0 deletions projects/http-handler-example/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div *ngIf="loading">
Loading...
</div>
<div *ngIf="!loading">
{{response | json}}
</div>
50 changes: 31 additions & 19 deletions projects/http-handler-example/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,46 @@
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Component, inject, OnInit } from '@angular/core';
import { handle } from 'angular-http-handler';
import { handle, setDefaultErrorHandler, setDefaultRetryCount, setDefaultRetryDelay } from 'angular-http-handler';

interface Post {
userId: number;
id: number;
title: string;
body: string;
}

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private apiUrl = 'YOUR API URL';
private apiUrl = 'https://jsonplaceholder.typicode.com/posts';
http = inject(HttpClient);

loading = false;
response: any[] = [];
response: any = null;

ngOnInit(): void {
this.http.get<any[]>(this.apiUrl).pipe(
handle(
(response) => {
this.response = response;
console.log(response)
},
(loading) => { // OPTIONAL - loader indicator
this.loading = loading;
console.log(loading)
},
(e) => console.log(e, 'custom'), // OPTIONAL - custom error handler
2, // OPTIONAL - retry count
1000, // OTIONAL - retry delay
)
).subscribe();
setDefaultErrorHandler((error: HttpErrorResponse) => {
console.log('deafult handler', error)
});
setDefaultRetryCount(0);
setDefaultRetryDelay(500);

this.http.get<Post[]>(this.apiUrl).pipe(handle(
(response) => {
this.response = response;
console.log(response)
},
(loading) => { // OPTIONAL - loader indicator
this.loading = loading;
console.log(loading)
},
[], // OPTIONAL - custom fallback value
(e) => console.log(e, 'custom'), // OPTIONAL - custom error handler
2, // OPTIONAL - retry count
1000, // OTIONAL - retry delay
)).subscribe();
}
}
3 changes: 2 additions & 1 deletion projects/http-handler-example/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HttpErrorResponse } from '@angular/common/http';
import { AppComponent } from './app.component';
import { setDefaultErrorHandler } from 'angular-http-handler';


@NgModule({
Expand All @@ -16,4 +17,4 @@ import { AppComponent } from './app.component';
],
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {}

0 comments on commit 5fd944d

Please sign in to comment.