One of the most important packages that come out of the box with angular is the HTTP
package, although it's incredible and easy to use it still has a limitation when it comes to deal with the Interceptors.
Almost in each Angular project, I used interceptors, at least one interceptor to add Authorization header with every request.
A while back I needed to skip adding that header for a specific request, but unfortunately, there's no direct way to tell the Authorization interceptor, don't add the header to this request!
unless you added a specific header or query param to mark this request.
But this was indirect and not good in the long term, so from this point, I decided to figure out a way to make this more declarative and obvious.
I started to play with request headers, a function that will accept a plain object that will be mapped out to HTTP headers that will be removed before sending the request out of the client, but again I didn't like this approach because it doesn't look as I want.
then I had a chance to extend the HttpClient
class so I can easily add what I want, I saw a lot of developer doing this approach before releasing the HttpClient to perform some logic before or after sending the request, but this just makes things worst for me.
Thus, I found a way to modify a module interface in order to add specific functionality to it, thanks to Typescript Module Augmentaion
it allows you to patch existing objects by importing and then updating them.
So the final thoughts were to extend the HttpClient
, add a custom method to it to pass custom options along with the request, use DI system to provide the CustomHttpClient
as HttpClient
, and finally using Module augmentation to augment the HttpClient
interface with the new custom method.
Let's start ^^
I'll not dig deep in explaining how you gonna do it, instead, I've combined all the work in one package and here's the source code to see how it works in details
- Run
npm install @ezzabuzaid/ngx-request-options
- Define your custom options interface
interface CustomOptions {
defaultUrl:boolean;
defaultAuth: boolean;
}
- Add
RequestOptionsModule
toAppModule
import { RequestOptionsModule } from '@ezzabuzaid/ngx-request-options';
@NgModule({
imports: [
HttpClientModule,
RequestOptionsModule.forRoot<CustomOptions>({
// Default options to be applied on all requests
defaultAuth: true;
defaultUrl: true
})
]
})
// Add those lines as they are
declare module '@angular/common/http/http' {
// Augment HttpClient with the new `configure` method
export interface HttpClient {
/**
* Configure request options.
*/
configure(options: Partial<CustomOptions>): HttpClient;
}
}
- Time to use it
- Use the new
configure
before the HTTP method with the options you want to use in the interceptros
- Use the new
@Injectable()
export class MyService {
constructor(private http: HttpClient) { }
getData() {
return this.http
.configure({ defaultUrl: false })
.get('endpoint');
}
}
- Inject the
RequestOptions
in the Interceptor
import { RequestOptions } from '@ezzabuzaid/ngx-request-options';
@Injectable()
export class UrlInterceptor implements HttpInterceptor {
constructor(private requestOptions: RequestOptions<CustomOptions>) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let url = request.url;
if (this.requestOptions.get(request, 'defaultUrl')) {
url = environment.endpointUrl + request.url;
}
return next.handle(this.requestOptions.clone(request, { url }));
}
}
That's it. with this setup, you can have the request communicate will with any interceptor
for more details please refer to the repo
Some of the use cases of interceptors maybe
- Add default URL to the outgoing request
- Dynamic caching for the response
- Show progress bar while a request on the fly
- Display a snack bar telling the state of the request
- Append Authorization header for a request
- Logging request metadata
- Error handling
- Unify Response content type
- Auto mapping the response body and there's more,
If you have any questions or feedback please comment about them.
Happy coding!
Top comments (1)
Thank's Friend , very helpful package