Using Axios as an Injectable Service in Angular
This guide explains how to integrate the Axios HTTP client into an
Angular application by wrapping it inside an injectable service. While
Angular provides its built-in HttpClient, developers often
prefer Axios for its interceptor handling, automatic JSON
transformation, or consistency across non-Angular projects. Below are
the direct steps and code examples required to set up Axios, configure a
base service, and inject it into Angular components using the dependency
injection system.
1. Install Axios
Install Axios in your Angular project via npm or yarn:
npm install axios2. Create the Axios Service
Generate an Angular service using the Angular CLI:
ng generate service services/axiosOpen the newly created axios.service.ts and set up an
Axios instance. This instance allows you to configure global settings
such as base URLs, headers, and timeouts:
import { Injectable } from '@angular/core';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
@Injectable({
providedIn: 'root',
})
export class AxiosService {
private axiosInstance: AxiosInstance;
constructor() {
this.axiosInstance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
this.setupInterceptors();
}
private setupInterceptors(): void {
// Request Interceptor
this.axiosInstance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('auth_token');
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response Interceptor
this.axiosInstance.interceptors.response.use(
(response) => response,
(error) => {
// Centralized error handling
console.error('API Error:', error.response?.status, error.message);
return Promise.reject(error);
}
);
}
public get<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
return this.axiosInstance.get<T>(url, config);
}
public post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
return this.axiosInstance.post<T>(url, data, config);
}
public put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
return this.axiosInstance.put<T>(url, data, config);
}
public delete<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {
return this.axiosInstance.delete<T>(url, config);
}
}3. Inject and Use the Service in a Component
With the service decorated with { providedIn: 'root' },
it is immediately available for dependency injection across the
application.
You can inject the service into a component using either constructor
injection or the inject() function.
Example Using Constructor Injection:
import { Component, OnInit } from '@angular/core';
import { AxiosService } from './services/axios.service';
interface User {
id: number;
name: string;
}
@Component({
selector: 'app-user-list',
template: `
<ul>
<li *ngFor="let user of users">{{ user.name }}</li>
</ul>
`,
})
export class UserListComponent implements OnInit {
users: User[] = [];
constructor(private axiosService: AxiosService) {}
async ngOnInit(): Promise<void> {
try {
const response = await this.axiosService.get<User[]>('/users');
this.users = response.data;
} catch (error) {
console.error('Failed to load users', error);
}
}
}Example Using the
inject() Function:
import { Component, OnInit, inject } from '@angular/core';
import { AxiosService } from './services/axios.service';
@Component({
selector: 'app-user-profile',
template: `<div>User details loaded</div>`,
})
export class UserProfileComponent implements OnInit {
private axiosService = inject(AxiosService);
async ngOnInit(): Promise<void> {
try {
const response = await this.axiosService.get('/profile');
console.log(response.data);
} catch (error) {
console.error('Error fetching profile', error);
}
}
}Structuring Axios this way ensures that request configurations, authentication headers, and error handling remain modular, testable, and maintainable throughout your Angular application.