brewdigital-requests v0.0.14
Brew Requests Angular
A request system for Angular
Install
npm install brewdigital-requests
oryarn add brewdigital-requests
Getting Started
First import
the BrewRequestsModule
into a one of your apps modules.
You will also need to import RouterModule
and HttpClientModule
from Angular.
import { NgModule } from '@angular/core';
import {HttpClientModule} from '@angular/common/http';
import {RouterModule} from '@angular/router';
import {BrewRequestsModule} from 'brewdigital-requests';
@NgModule({
// ...
imports: [
// ...
HttpClientModule,
RouterModule,
BrewRequestsModule
],
// ...
})
export class AppModule {}
Setting Base API URL
Then add a base route for the API. This will be prepended to API requests unless withApiUrl
is set to false (see below for more on this).
import { NgModule } from '@angular/core';
import {BrewRequestsModule} from 'brewdigital-requests';
@NgModule({
// ...
providers: [
{provide: 'apiUrl', useValue: 'https://jsonplaceholder.typicode.com'},
],
// ...
})
export class AppModule {}
Making Requests
To make a single request in a component you can use a standalone request by providing one of the following services.
- GetRequestService
- PostRequestService
- PutRequestService
- DeleteRequestService
- FileRequestService
GetRequestService example
import {Component, OnInit} from '@angular/core';
import {GetRequestService} from 'brewdigital-requests';
@Component({
selector: 'app-get-request',
providers: [
GetRequestService,
]
})
export class GetRequestComponent implements OnInit {
constructor(
private getRequest: GetRequestService,
) {}
ngOnInit(): void {
this.getRequest.fetch('/posts').subscribe(res => console.log(res));
}
}
Passing Parameters and Values
Params
The requests fetch
method accepts and args
parameter that can be used to pass params
and values
to the request.
For example passing a params
object with {with: 'comments'}
will append ?with=comments
to the url.
GetRequestService with params example
this.getRequest.fetch('/posts', {params: {with: 'comments'}})
.subscribe(res => console.log(res));
Values
Post and Put requests require a values
key to be passed to the args
parameter. Values will be posted in the body of the request as JSON
PostRequestService with values example
this.postRequest.fetch('/posts', {values: {title: 'A great post', body: 'The body of the post'}})
.subscribe(res => console.log(res));
PutRequestService with values example
this.putRequest.fetch('/posts/1', {values: {title: 'A post', body: 'New body for the post'}})
.subscribe(res => console.log(res));
Response Transforms
Before the response is sent back to the component the response status code is checked and the data is transformed to a consistent data type by a transformer.
By default success and error responses are handled using the SuccessResponseTransformer
and ErrorResponseTransformer
respectively.
If the request is successful the data will return with a type
of responseType.SUCCESS
If the request returns an error the status code will be checked and the type
will be set to one of the following error types
- responseType.ERROR
- responseType.SERVER_ERROR
- responseType.INVALID
- responseType.AUTHORISATION_FAILED
- responseType.UNAUTHORISED
- responseType.NOT_FOUND
These can be handled in the subscribe using a switch
statement.
GetRequestService date example
import {Component, OnInit} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {GetRequestService, responseType} from 'brewdigital-requests';
@Component({
selector: 'app-get-request',
template: `
<div>
<div class="post">
<h1>{{post.title}}</h1>
<h1>{{post.body}}</h1>
</div>
</div>
`,
providers: [
GetRequestService,
]
})
export class GetRequestComponent implements OnInit {
private _post$ = new BehaviorSubject({
title: '',
body: ''
});
get post() {
return this._post$.value;
}
constructor(
private getRequest: GetRequestService,
) {}
ngOnInit(): void {
this.getRequest.fetch('/posts/1')
.subscribe(res => {
switch(res.type) {
case responseType.SUCCESS:
this._post$.next(res.data);
break;
case responseType.UNAUTHORISED:
// Handle Unauthorised
console.log('You are not authorised to request this data');
break;
case responseType.NOT_FOUND:
// Handle Not Found
console.log('The data requested does not exist');
break;
default:
console.log('Handle Error')
}
});
}
}
Is Loading Observable
When requests are sent an isLoading
observable is set to true
. Components can use this to display loaders and disable inputs, or whatever else they might want to do while a request is being resolved.
GetRequestService isLoading example
import {Component, OnInit} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {GetRequestService, responseType} from 'brewdigital-requests';
@Component({
selector: 'app-get-request',
template: `
<div>
<p *ngIf="getRequest.isLoading">Loading...</p>
<div class="post" *ngIf="!getRequest.isLoading">
<h1>{{post.title}}</h1>
<p>{{post.body}}</p>
</div>
</div>
`,
providers: [
GetRequestService,
]
})
export class GetRequestComponent implements OnInit {
private _post$ = new BehaviorSubject({
title: '',
body: ''
});
get post() {
return this._post$.value;
}
constructor(
private getRequest: GetRequestService,
) {}
ngOnInit(): void {
this.getRequest.fetch('/posts/1')
.subscribe(res => {
switch(res.type) {
case responseType.SUCCESS:
this._post$.next(res.data);
break;
default:
console.log('Handle Error')
}
});
}
}
withApiUrl Argument
If you want to use URL other than the apiUrl
provided in root, you can set the withApiUrl
argument to false
and pass a full url to the fetch
method.
this.getRequest.fetch('http://localhost/api/an-endpoint', {withApiUrl: false})
Request Collection
If you need to make a number of requests within the same component use the RequestCollectionService
.
This is just a wrapper around the instantiation of request services.
The first parameter passed to the request get, post, put, delete or file method is an id that can be used to look up the request in the collection.
RequestCollectionService example
import {Component, OnInit} from '@angular/core';
import {RequestCollectionService} from 'brewdigital-requests';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [
RequestCollectionService,
]
})
export class AppComponent implements OnInit {
constructor(
private request: RequestCollectionService,
) {}
ngOnInit(): void {
this.request.get('get_todo', '/todos/1').subscribe(res => console.log(res));
this.request.post('post_todo', '/todos', {values: {title: 'hello', completed: false}}).subscribe(res => console.log(res));
this.request.put('put_todo', '/todos/1', {values: {title: 'hello', completed: true}}).subscribe(res => console.log(res));
this.request.delete('delete_todo', '/todos/1').subscribe(res => console.log(res));
}
}
RequestCollectionService getIsLoadingById
import {Component, OnInit} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {RequestCollectionService} from 'brewdigital-requests';
@Component({
selector: 'app-root',
template: `
<div>
<p *ngIf="request.getIsLoadingById('get_todo')">Loading...</p>
<div class="todo" *ngIf="!request.getIsLoadingById('get_todo')">
<h1>{{todo.title}}</h1>
<p>{{todo.completed ? 'Done' : 'Not Done'}}</p>
</div>
</div>
`,
providers: [
RequestCollectionService,
]
})
export class AppComponent implements OnInit {
private _todo$ = new BehaviorSubject({
title: '',
completed: false
});
get todo() {
return this._todo$.value;
}
constructor(
private request: RequestCollectionService,
) {}
ngOnInit(): void {
this.request.get('get_todo', '/todos/1')
.subscribe(res => console.log(res));
this.request.post('post_todo', '/todos', {values: {title: 'hello', completed: false}})
.subscribe(res => console.log(res));
this.request.put('put_todo', '/todos/1', {values: {title: 'hello', completed: true}})
.subscribe(res => console.log(res));
this.request.delete('delete_todo', '/todos/1')
.subscribe(res => console.log(res));
}
}