http-request-manager
TypeScript icon, indicating that this package has built-in type declarations

15.0.24 • Public • Published

Request Manager Service Documentation

Summary of the Lib

The HTTPManagerService is a collection of 4 services for HTTP and Local Storage management.

Installation

npm install http-request-manager

Services

HTTP Manager Service:

Http service simplifies http requests in the following ways

  • Define a fixed endpoint service
  • Provide a fixed set of headers or add to the headers on request
  • Proxy Config Support
  • Adapter for strict type checking for incoming data
  • Mapper for data transformation for outgoing data
  • Polling requests automatically
  • Retry requests if failure
  • Stream http requests from endpoint service
  • Display Error provides a Toast (Snackbar) notification on error

HTTP State Manager Service

Http service simplifies http request state management in the following ways

  • Inherits from HTTP Manager Service for config options
  • Creates a Component Store state (NGRX)
  • Selectors for data and selecting data records
  • Create, Update and Delete automatically updates data by endpoint and state on success
  • Get keeps state of records

Database Storage Manager (Coming soon)

  • Inherits from HTTP State Manager Service for config options
  • Manages HTTP Requests caching data in local DB (IndexedDB) using DixieJS
  • Requests check first local DB and if data is not stale, request is made and updates DB
  • Expiry time/date can be set for DB records for caching

Local/Session Storage

  • Allows for Local and Storage management for data Persistence
  • Component Store (NGRX) State for changes on storage
  • Encryption for data
  • Expiry time/date can be set for stores

Using the Services

There are three ways to use the service, depending on your needs:

Injecting the Service (Single Usage)

httpManagerService = inject(HTTPManagerService)
  • This approach provides a singleton state for the service, as services are provided in root (@Injectable({ providedIn: 'root' })).

  • Any components or services that inject this service will share the same state, meaning they all have access to:

    • data$ (observable for data)
    • isPending$ (loading state)
    • countDown$ (loading state)
    • error$ (error state)
    • Methods associated with the service
    • Since there is only one shared state, it can be reused across components without creating new instances.

    Here is a very simple example

      //Define your API request details using the `ApiRequest` adapter
      const apiOptions = ApiRequest.adapt({
        server: 'myApiUrl/rest/clients' // or ['myApiUrl', 'rest', 'clients']
      })
    
    onFetchData() {
    
        this.httpManagerService.getRequest<any>(apiOptions)
        .pipe(
          catchError(error => {
            return throwError(() => this.errorHandling(error, 'GET'))
          })
        ).subscribe(data => console.log(data)))
    
      }

Example

In this example, we define the endpoint URL as myApiUrl. This will return the data from the observable for your use case.

The endpoint can be:

A direct URL (e.g., https://apple.com/clients). A proxy-config file (recommended to avoid CORS issues). A string, an array of strings, or numbers—similar to Angular’s Router.navigate() API. The HTTP Service Manager automatically sanitizes the endpoint by removing redundant / characters and validating the URL.

You can also add query parameters by passing an object:

  { sortBy: 'asc', filter: ['samples', 'testing'] }

This translates to: https://apple.com/clients?sortBy=asc&filter=samples,testing

There are a number of other options available in the ApiRequest adapter

Extending a Component or Service with the Service (Multiple Instances - preferred method)

This approach creates a new instance of the service for each component or service that extends it, ensuring each instance maintains its own independent state.

Observables

  • Similar to the first approach, instead of one instance of the state you are creating a new state instance

  • CRUD operations return Observables, similar to HttpClient.

  • This allows for custom error handling and executing additional actions after the request completes.

  • Since HTTP requests are asynchronous, you must subscribe to the Observable to receive data:

      myService.getData().subscribe(response => {
        console.log(response);
      });
  • Alternatively, you can use the async pipe for automatic subscription and cleanup:

      {{ myData$ | async }}

Example

First we need to extend the Component or Service (recommended approach) with the HTTPManagerService

Component Example:

export class RequestManagerDemoComponent extends HTTPManagerService<any> implements OnInit {

  constructor() { 
    super()
  }
}

Service Example:

@Injectable({
  providedIn: 'root'
})
export class myAPIService extends HTTPManagerService<any> {

  constructor() { 
    super()
  }

}

In this example, we define the endpoint URL as myApiUrl. This will return the data from the observable for your use case.

The endpoint can be:

A direct URL (e.g., https://apple.com/clients). A proxy-config file (recommended to avoid CORS issues). A string, an array of strings, or numbers—similar to Angular’s Router.navigate() API. The HTTP Service Manager automatically sanitizes the endpoint by removing redundant / characters and validating the URL.

You can also add query parameters by passing an object:

  { sortBy: 'asc', filter: ['samples', 'testing'] }

This translates to: https://apple.com/clients?sortBy=asc&filter=samples,testing

Lets define these query params as a variable called PARAMS and use them in the following request.

There are a number of other options available in the ApiRequest adapter

No we can define a method: In this example take note that the clientID has been passed to the method and the param after the apiOptions allows for further customization for the api request being made. In this case we extended the the base path defined in the ApiRequest options. We also added the PARAMS for query parameters.

Define your API request options using the 'ApiRequest' adapter

  const apiOptions = ApiRequest.adapt({
    server: ['myApiUrl', 'rest', 'clients']
  })

  // Dynamically change these params
  const PARAMS = {
    sortBy: 'asc',
    filter: ['samples', 'testing']
  }

  onFetchData(clientId) {

    this.httpManagerService.getRequest<any>(apiOptions, [clientId, this.PARAMS])
    .pipe(
      catchError(error => {
        return throwError(() => this.errorHandling(error, 'GET'))
      })
    ).subscribe(data => console.log(data)))

  }

State Observable

  • When executing CRUD operations, their results are automatically pushed into the data$ observable within the service.
  • This means you can bind the data$ observable to a component to automatically update UI elements.
  • Using this approach enables state management across components and allows data refresh actions without needing additional logic.

Example

First we need to extend the Component or Service (recommended approach) with the HTTPManagerService

Component Example: The structure would be: Component extends HTTPManagerService

export class RequestManagerDemoComponent extends HTTPManagerService<any> implements OnInit {

  constructor() { 
    super()
  }
}

Service Example: The structure would be: Component injects a service call clientsService and clientsService extends HTTPManagerService

@Injectable({
  providedIn: 'root'
})
export class myAPIService extends HTTPManagerService<any> {

  constructor() { 
    super()
  }

}

In this example, we define the endpoint URL as myApiUrl.

Lets define these query params as a variable called PARAMS and use them in the following request.

No we can define a method: In this example the clientID has been passed to the method. We also added the PARAMS for query parameters.

Define your API request options using the 'ApiRequest' adapter

  const apiOptions = ApiRequest.adapt({
    server: ['myApiUrl', 'rest', 'clients']
  })

  // Dynamically change these params
  const PARAMS = {
    sortBy: 'asc',
    filter: ['samples', 'testing']
  }

  onFetchData(clientId: number) {
    this.httpManagerService.getRequest<any>(apiOptions, [clientId, this.PARAMS]).subscribe()
  }

In the above case we are not using the data returning from the Observable but rather executing the api call, like a refresh if called again

To access the data from the observable, you need to bind the observable if your using a component that injects the service that extends the HTTPManagerService

In the component where the service was injected, we define

  data$ = this.clientsService.data$
  isPending$ = this.clientsService.isPending$
  error$ = this.clientsService.error$

By doing this gives your component the state of the data and other feedback states for the request that now you can use in your template.

  {{ data$ | async }}
  {{ isPending$ | async }}
  {{ error$ | async }}

ApiRequest Options

The following are the available options when configuring an ApiRequest object:

apiRequest = ApiRequest.adapt({
  server: string,
  path: any[],
  headers: any,
  adapter?: any,
  mapper?: any,
  polling?: number, // in seconds (undefined | 0 = none)
  retry: RetryOptions,
  stream?: boolean
  displayError: boolean
});
Property Description Type Required
server The base URL or service endpoint for the API request. string
path Additional paths to append to the base URL for constructing the full API endpoint. any[]
headers Custom headers to include in the request, provided as an object. any
adapter A model adapter used to transform incoming data (e.g., DistrictData.adapt). any
mapper A model adapter used to map outgoing data before sending it to the server (e.g., DistrictData.mapper). any
polling Enables periodic polling, where the request will be made every specified number of seconds. number (seconds)
retry Retry logic using RetryOptions, which includes:
- times: Number of retry attempts.
- delay: Delay in milliseconds between retries.
RetryOptions
stream A flag to indicate whether the request expects a stream of data from the server. boolean
displayError A flag to indicate whether to present the error from the request in a snackbar notification. boolean

Additional Observables for Request Status

  • countdown$: If polling is active, this property gives feedback on when the next request will take place. It starts from the specified time in seconds and counts down to 0, triggering the next request and restarting the countdown.
  • error$: This returns any HTTP error that occurs during the request.
  • isPending$: This boolean value indicates whether the request is pending (true) or has been completed (false).
  • data$: You can access the data fetched in the request using the data$ observable. This provides the response from the server, which can be used for further processing or displaying in the UI.

Importing Module forRoot() Configuration

Available Interceptors

There are 3 interceptors that you can import into your project for api requests.

You may add these interceptors in your AppModule file as providers and import them into as providers.

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: WithCredentialsInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: RequestHeadersInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: RequestErrorInterceptor, multi: true }
],

Or you can use all intercepts above by importing the HttpRequestManagerModule in your AppModule

  • RequestErrorInterceptor

This interceptor handles errors of type 400 and 500. This interceptor is applicable when you need to display UI for the user to indicate a server or request error has occurred. The Status and Error Text is displayed in a toast-message modal.

  • WithCredentialsInterceptor

    Adds to your request header

    { credentials: true }
  • RequestHeadersInterceptor

    Adds to your request - current local language (i18n) selection and current date to every request

    {
      'Content-Type': 'application/json',
      'Accept-Language': this.language || 'en-CA',
      'Current-Date': this.currentDate
    }

Readme

Keywords

none

Package Sidebar

Install

npm i http-request-manager

Weekly Downloads

23

Version

15.0.24

License

none

Unpacked Size

1.64 MB

Total Files

143

Last publish

Collaborators

  • wavecoders