DEV Community

Cover image for API Handling in JavaScript & React: From Basics to Pro-Level
Shubham Tiwari
Shubham Tiwari

Posted on

API Handling in JavaScript & React: From Basics to Pro-Level

Learn JavaScript api handling with fetch, axios, and error handling. API handling refers to making HTTP requests to a server to fetch or send data.

Hello my fellow frontend developers, today i will be discussing one of the most important concept in javascript, api handling.

  • I'll be creating my code snippets on Scribbler.live first, which is a fantastic platform that allows you to run a JavaScript Notebook, Online Compiler, and Editor without the need for manual setup.
  • Additionally, I am including a link to code snippets that includes all of the code examples so you can open the snippet and run it yourself to see the results.
  • I will be using scrib.show from scribbler.live, it is equivalent to console.log
  • Only examples from fetch api will be added to scribbler as currently it doesn't support axios and react.

Let's dive in

Table of contents

What is API?

  • An API is a set of definitions and protocols that enable two software components to communicate.
  • Some of the technologies used to write apis are:
    • Javascript (Express framework)
    • Python (Django framework)
    • Go (Gin framework)
    • Java (Spring Boot framework)
    • C# (ASP.NET Core framework)

What is API handling?

API handling refers to making HTTP requests to a server to fetch or send data. In JavaScript and React, API calls are commonly handled using fetch, Axios, or libraries like React Query or TanStack Query.

HTTP Methods

APIs work with different HTTP methods, each serving a specific purpose:

  • GET – Fetch data from the server.
  • POST – Send new data to the server.
  • PUT – Update existing data (replaces the entire resource).
  • PATCH – Update part of an existing resource.
  • DELETE – Remove data from the server.

Making API Requests in JavaScript

Fetch method

The native fetch API method is commonly used to interact with APIs. It accepts 2 arguments - API endpoint and options objects to pass headers, body, method, etc.

Fetch method with GET request

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => response.json())
  .then(data => scrib.show(data))
  .catch(error => scrib.show('Error:', error));
Enter fullscreen mode Exit fullscreen mode

Fetch method with POST request

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST', // type of method GET, POST, PUT, POST, DELETE
  headers: {
    'Content-Type': 'application/json' // headers like referrer, bearer, content-type, custom headers, etc.
  },
  // body of the POST request which we are sending to the api
  body: JSON.stringify({
    title: 'Javascript is awesome',
    body: 'Did you know you could write html and javascript combined in scribbler',
    userId: 1
  })
})
  .then(response => response.json())
  .then(data => scrib.show(data))
  .catch(error => scrib.show('Error:', error));
Enter fullscreen mode Exit fullscreen mode

Error handling with fetch method

fetch('https://jsonplaceho.typicode.com/posts') // incorrect api endpoint
  .then(response => response.json())
  .then(data => scrib.show(data))
  .catch(error => scrib.show('Error:', error)); // will run this block of code and throws error
Enter fullscreen mode Exit fullscreen mode

Handling api with try catch finally block

async function getData() {
  try {
    let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
    if (!response.ok) throw new Error('Network response was not ok'); // return boolean for valid/invalid responses
    let data = await response.json();
    scrib.show(data)
  } catch (error) {
    scrib.show('Fetch error:', error); // will handle the error if the fetch fails
  } finally {
    scrib.show(Fetch request is done); // will run no matter a response is valid or invalid or fetch fails
  }
}
getData()
Enter fullscreen mode Exit fullscreen mode

Checkout this embed to run the code example mentioned above

Axios

Axios is a javascript library that simplifies API handling and provides better error handling.

Axiox with GET request

import axios from "axios"

// all http methods could be chained with axios
axios.get('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => scrib.show(response.data))
  .catch(error => scrib.show('Error:', error));
Enter fullscreen mode Exit fullscreen mode

Axios with POST request

import axios from "axios"

// json body is passed separately as second argument and rest of the options as third argument
axios.post('https://jsonplaceholder.typicode.com/posts', {
   title: 'Javascript is awesome',
    body: 'Did you know you could write html and javascript combined in scribbler',
    userId: 1
}, {
  headers: { 'Content-Type': 'application/json' }
})
  .then(response => scrib.show(response.data)) // automatically converts the response to json format
  .catch(error => scrib.show('Error:', error));
Enter fullscreen mode Exit fullscreen mode

Error handling with axios

import axios from "axios"

axios.get('https://jsonpl.typicode.com/posts') // incorrect url
  .then(response => scrib.show(response.data))
  .catch(error => {
// has multiple error response for different scenarios
    if (error.response) {
      scrib.show('Server responded with:', error.response.status);
    } else if (error.request) {
      scrib.show('No response received');
    } else {
      scrib.show('Error setting up request:', error.message);
    }
  });

Enter fullscreen mode Exit fullscreen mode

Handling api with try catch finally block

import axios from "axios";

const fetchData = async () => {
  try {
    const response = await axios.get("https://jsonplaceholder.typicode.com/posts");
    console.log("Data fetched successfully:", response.data);
    return response.data;
  } catch (error) {
    console.error("Error fetching data:", error.response?.data || error.message);
    return null;
  } finally {
    console.log("Fetch is done")
  }
};

fetchData();
Enter fullscreen mode Exit fullscreen mode

React (using useEffect and useState)

import { useEffect, useState } from 'react';

function Posts() {
  // Creating states for data and error messages
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState(null);

  // Performing data fetching in useEffect, will run only once on page load
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => {
        if (!response.ok) {
          throw new Error('Failed to fetch');
        }
        return response.json();
      })
      .then(data => setPosts(data))
      .catch(error => setError(error.message));
  }, []);

  if (error) return <p>Error: {error}</p>;

  return (
    <div>
      <h2>Posts</h2>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default Posts;
Enter fullscreen mode Exit fullscreen mode

Tanstack query library

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

// fetch the data and return it
const fetchPosts = async () => {
  const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts');
  return data;
};

function Posts() {
  // tanstack has builtin data, error, loading states
  const { data: posts, error, isLoading } = useQuery({ queryKey: ['posts'], queryFn: fetchPosts });

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

export default Posts;
Enter fullscreen mode Exit fullscreen mode

Conclusion

API handling in JavaScript and React involves:

  • Using fetch or Axios to make API calls.
  • Handling different HTTP methods (GET, POST, PUT, DELETE).
  • Implementing proper error handling.
  • Managing headers for authentication.
  • Using useEffect for API calls in React.
  • Leveraging React Query for efficient state management.

That's it for this post, Let me know if i could do any improvements in this article. Also, do check Scribbler.live website.

You can contact me on -

Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

You can help me with some donation at the link below Thank you👇👇
https://www.buymeacoffee.com/waaduheck

Also check these posts as well

Top comments (5)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

I'm on a quest against if (!response.ok) throw....

The Ugly Truth: All Popular fetch() Wrappers Do It Wrong

Discover the reality behind axios, ky and popular data-fetching NPM packages and how to replace them.

favicon webjose.hashnode.dev
Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

Try catch is an important wrapper as it avoids the termination of the app if there is an exception during data fetching, best example would be data fetching in next js, If you don't use try catch and an exception occurs, your webpage will crash

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

I'm not against generic try..catch. I'm against throwing an error when a non-OK response is received via fetch() because then you are forced to write an extra try..catch.

Thread Thread
 
shubhamtiwari909 profile image
Shubham Tiwari

Yeah, that is just an example, in a real world project, we will be adding an error state and a UI for that exception.

Thread Thread
 
z2lai profile image
z2lai

I thought this article was about going pro! Anyway, what about retry logic, have you seen that implemented in the real world?