Lesson 76 of 60 – TypeScript with Axios
100%

TypeScript with Axios

Axios is a popular HTTP client that can be used in React Native applications to communicate with APIs. With TypeScript, Axios can be combined with interfaces and generic types to make API requests safer and easier to maintain.

In this lesson, we will learn how to make GET, POST, PUT, and DELETE requests, type API responses, handle errors, send request data, and use Axios with React Native state.

Note: Axios is asynchronous, so API functions normally return Promises. TypeScript can describe both the request data and the expected response.

1. What is Axios?

Axios is an HTTP client used to send requests to web APIs.

It can be used for operations such as:

  • GET requests
  • POST requests
  • PUT requests
  • PATCH requests
  • DELETE requests

2. Installing Axios

Axios can be installed using npm:

npm install axios

After installation, it can be imported into a TypeScript file.

3. Importing Axios

import axios from "axios";

The imported Axios object can then be used to make HTTP requests.

4. Basic GET Request

const response =
    await axios.get(
        "https://example.com/api/users"
    );

console.log(response.data);

Axios places the response body inside the data property.

5. Creating an API Interface

interface User {
    id: number;
    name: string;
    email: string;
}

This interface describes the expected structure of a user.

6. Typing an Axios Response

const response =
    await axios.get<User>(
        "https://example.com/api/user"
    );

const user: User =
    response.data;

The generic type <User> tells TypeScript what type is expected in response.data.

7. Axios Response Type

import axios, {
    AxiosResponse
} from "axios";

const response:
    AxiosResponse<User> =
    await axios.get<User>(
        "https://example.com/api/user"
    );

Axios also provides the AxiosResponse type when you need to describe the complete response object.

8. Typing an Array Response

const response =
    await axios.get<User[]>(
        "https://example.com/api/users"
    );

const users: User[] =
    response.data;

User[] tells TypeScript that the API returns an array of User objects.

9. Creating a Typed API Function

const getUsers =
    async (): Promise<User[]> => {

    const response =
        await axios.get<User[]>(
            "https://example.com/api/users"
        );

    return response.data;
};

The function returns a Promise containing a User array.

10. Using Axios with useState

const [users, setUsers] =
    useState<User[]>([]);

const loadUsers = async (): Promise<void> => {

    const response =
        await axios.get<User[]>(
            "https://example.com/api/users"
        );

    setUsers(response.data);
};

11. Axios with useEffect

useEffect(() => {

    const loadUsers = async (): Promise<void> => {

        const response =
            await axios.get<User[]>(
                "https://example.com/api/users"
            );

        setUsers(response.data);
    };

    loadUsers();

}, []);

12. POST Request

A POST request can be used to send new data to an API.

const response =
    await axios.post(
        "https://example.com/api/users",
        {
            name: "Rahul",
            email: "rahul@example.com"
        }
    );

13. Typing POST Data

interface CreateUser {
    name: string;
    email: string;
}

const newUser: CreateUser = {
    name: "Rahul",
    email: "rahul@example.com"
};

The interface ensures that the request data follows the expected structure.

14. Typed POST Request

const newUser: CreateUser = {
    name: "Rahul",
    email: "rahul@example.com"
};

const response =
    await axios.post<User>(
        "https://example.com/api/users",
        newUser
    );

const user: User =
    response.data;

15. PUT Request

A PUT request can be used to update an existing resource.

const response =
    await axios.put<User>(
        "https://example.com/api/users/101",
        {
            name: "Rahul Kumar",
            email: "rahul@example.com"
        }
    );

16. DELETE Request

await axios.delete(
    "https://example.com/api/users/101"
);

DELETE requests are commonly used to remove a resource from an API.

17. Query Parameters

Axios can send query parameters using the params option.

const response =
    await axios.get<User[]>(
        "https://example.com/api/users",
        {
            params: {
                page: 1,
                limit: 10
            }
        }
    );

18. Request Headers

const response =
    await axios.get<User[]>(
        "https://example.com/api/users",
        {
            headers: {
                "Content-Type":
                    "application/json"
            }
        }
    );

Headers can provide additional information to the server.

19. Loading State

const [loading, setLoading] =
    useState<boolean>(false);

const loadUsers = async (): Promise<void> => {

    try {

        setLoading(true);

        const response =
            await axios.get<User[]>(
                "https://example.com/api/users"
            );

        setUsers(response.data);

    } finally {

        setLoading(false);

    }
};

20. Error Handling

const [error, setError] =
    useState<string | null>(null);

const loadUsers = async (): Promise<void> => {

    try {

        setError(null);

        const response =
            await axios.get<User[]>(
                "https://example.com/api/users"
            );

        setUsers(response.data);

    } catch (error) {

        setError(
            "Unable to load users"
        );

    }
};

21. Typed Axios Errors

import axios from "axios";

try {

    await axios.get(
        "https://example.com/api/users"
    );

} catch (error) {

    if (axios.isAxiosError(error)) {

        console.log(
            error.message
        );

    } else {

        console.log(
            "Unknown error"
        );

    }
}

axios.isAxiosError() can help determine whether an error came from Axios.

22. Axios Instance

An Axios instance can be created when an application uses the same base URL or common configuration for many requests.

import axios from "axios";

const api = axios.create({
    baseURL:
        "https://example.com/api"
});

Requests can then use relative paths.

const response =
    await api.get<User[]>("/users");

23. API Service Functions

export const getUsers =
    async (): Promise<User[]> => {

    const response =
        await api.get<User[]>("/users");

    return response.data;
};

export const getUser =
    async (id: number): Promise<User> => {

    const response =
        await api.get<User>(
            `/users/${id}`
        );

    return response.data;
};

Keeping API calls in service functions can keep screen components cleaner.

24. Common Axios TypeScript Mistakes

  • Using any for every API response.
  • Forgetting to provide the response type.
  • Confusing response with response.data.
  • Sending incorrectly typed request data.
  • Not handling API errors.
  • Ignoring loading states.
  • Using incorrect property names from API responses.

25. Best Practices

  • Create interfaces for important API resources.
  • Use Axios generics such as axios.get<User>().
  • Type request data separately when appropriate.
  • Keep API functions separate from UI components.
  • Handle loading and error states.
  • Use Axios instances for common configuration.
  • Use axios.isAxiosError() when Axios-specific error handling is needed.

26. Axios with FlatList

const [users, setUsers] =
    useState<User[]>([]);

const loadUsers = async (): Promise<void> => {

    const response =
        await axios.get<User[]>(
            "https://example.com/api/users"
        );

    setUsers(response.data);
};

<FlatList<User>
    data={users}
    keyExtractor={(item) =>
        item.id.toString()
    }
    renderItem={({ item }) => (

        <Text>
            {item.name}
        </Text>

    )}
/>

27. Axios with a Typed API Response

interface User {
    id: number;
    name: string;
    email: string;
}

interface UserResponse {
    success: boolean;
    users: User[];
}

const response =
    await axios.get<UserResponse>(
        "https://example.com/api/users"
    );

if (response.data.success) {

    setUsers(
        response.data.users
    );

}

A response interface can describe both metadata and the actual records.

28. Complete TypeScript Axios Example

import React, {
    useEffect,
    useState
} from "react";

import {
    View,
    Text,
    FlatList,
    ActivityIndicator,
    StyleSheet
} from "react-native";

import axios from "axios";

interface User {
    id: number;
    name: string;
    email: string;
}

interface UserResponse {
    success: boolean;
    users: User[];
}

const api = axios.create({
    baseURL:
        "https://example.com/api"
});

export default function App(): React.JSX.Element {

    const [users, setUsers] =
        useState<User[]>([]);

    const [loading, setLoading] =
        useState<boolean>(true);

    const [error, setError] =
        useState<string | null>(null);

    const loadUsers =
        async (): Promise<void> => {

        try {

            setLoading(true);
            setError(null);

            const response =
                await api.get<UserResponse>(
                    "/users"
                );

            if (response.data.success) {

                setUsers(
                    response.data.users
                );

            }

        } catch (error) {

            if (axios.isAxiosError(error)) {

                setError(
                    "Unable to load users"
                );

            } else {

                setError(
                    "An unexpected error occurred"
                );

            }

        } finally {

            setLoading(false);

        }
    };

    useEffect(() => {

        loadUsers();

    }, []);

    if (loading) {

        return (
            <View style={styles.center}>
                <ActivityIndicator />
                <Text>
                    Loading users...
                </Text>
            </View>
        );

    }

    if (error) {

        return (
            <View style={styles.center}>
                <Text>
                    {error}
                </Text>
            </View>
        );

    }

    return (
        <View style={styles.container}>

            <Text style={styles.title}>
                User List
            </Text>

            <FlatList<User>
                data={users}

                keyExtractor={(item) =>
                    item.id.toString()
                }

                renderItem={({ item }) => (

                    <View style={styles.card}>

                        <Text
                            style={styles.name}
                        >
                            {item.name}
                        </Text>

                        <Text>
                            {item.email}
                        </Text>

                    </View>

                )}
            />

        </View>
    );
}

const styles = StyleSheet.create({

    container: {
        flex: 1,
        padding: 20
    },

    center: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center"
    },

    title: {
        fontSize: 24,
        fontWeight: "bold",
        marginBottom: 15
    },

    card: {
        padding: 15,
        marginBottom: 10,
        borderWidth: 1,
        borderRadius: 8
    },

    name: {
        fontSize: 18,
        fontWeight: "bold"
    }

});

29. Benefits of Axios with TypeScript

  • Typed API responses.
  • Typed request data.
  • Better code completion.
  • Reusable API service functions.
  • Clear API response structures.
  • Better error handling.
  • Easier integration with React Native state and FlatList.
  • Improved maintainability of larger applications.

30. Summary

Axios provides a convenient way to communicate with APIs in React Native. TypeScript makes Axios requests safer by allowing us to define request and response structures with interfaces and generic types.

You should now understand Axios installation, GET, POST, PUT, and DELETE requests, typed responses, request data, query parameters, headers, loading and error states, Axios instances, API service functions, FlatList integration, and complete typed Axios examples.

📌 Key Points

  • Install Axios with npm install axios.
  • Use Axios methods such as get(), post(), put(), and delete().
  • Use generics such as axios.get<User>() to type responses.
  • Use interfaces to describe API request and response data.
  • Use response.data to access the response body.
  • Handle loading and error states.
  • Use Axios instances for common API configuration.
  • Keep API service functions separate from UI components when appropriate.

🧠 Quick Quiz

Question: Which syntax can be used to tell Axios that a GET request returns an array of User objects?