Skip to main content

Query Examples

Fetch API

Fetch from cURL

curl "https://jsonplaceholder.typicode.com/posts/1"
-X GET \
-H "Content-Type: application/json"

Fetch List of Items React/TS

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

interface Post {
userId: number;
id: number;
title: string;
body: string;
}

export default function MyComponent() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [posts, setPosts] = useState<Post[]>([]);

useEffect(() => {
async function fetchData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/');
const data = await response.json();
setPosts(data);
setLoading(false);
} catch (error) {
setError(error.message);
setLoading(false);
}
}
fetchData();
}, []);

if (loading) {
return <p>Loading...</p>;
}

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

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

Fetch API Async Await

(async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
})();

Fetch API Async Await with Typescript

interface MyData {
id: number;
name: string;
}

const fetchData = async (): Promise<MyData> => {
try {
const response = await fetch('/data');
const data = await response.json();
return data;
} catch (error) {
console.error(error);
throw error;
}
};

fetchData().then(data => {
console.log(data);
});

Using node-fetch with Typescript, casting data to interface

import fetch from 'node-fetch';

interface UserData {
id: number;
title: string;
body: string;
}

const fetchData = async (): Promise<UserData> => {
try {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/1`
);
const data = await response.json();
return data as UserData;
} catch (error) {
console.error(error);
throw error;
}
};

fetchData().then((data) => {
console.log(data);
});

Fetch API promises/then

fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

Fetch API async/await POST body with error handling

(async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
})
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
})();

Fetch PATCH with Authorization token

(async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer myToken'
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
credentials: 'include'
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
})();

Fetch API with extra options

(async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts?userId=1', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer myToken',
'x-api-key': 'your-api-key'
},
cache: 'no-cache',
mode: 'cors',
redirect: 'follow',
referrerPolicy: 'no-referrer'
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
})();

Fetch with WebWorker

// In your web worker script:

self.addEventListener('message', async event => {
try {
const response = await fetch(event.data.url);
const data = await response.json();
self.postMessage({ result: data });
} catch (error) {
self.postMessage({ error: error.message });
}
});

// In your main script:

const worker = new Worker('worker.js');
worker.addEventListener('message', event => {
if (event.data.result) {
console.log(event.data.result);
} else {
console.error(event.data.error);
}
});
worker.postMessage({ url: 'https://jsonplaceholder.typicode.com/posts/1' });

Fetch with AbortController

const controller = new AbortController();
const signal = controller.signal;

(async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1', { signal });
const data = await response.json();
console.log(data);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request aborted!');
} else {
console.error(error);
}
}
})();

setTimeout(() => {
controller.abort();
}, 5000);

Fetch Uploading Data

(async () => {
try {
const response = await fetch('https://your-api-endpoint.com/upload', {
method: 'POST',
body: new FormData(document.getElementById('upload-form')),
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
})();

Fetch Uploading a File in React

import React, { useState } from 'react';

function FileUpload() {
const [selectedFile, setSelectedFile] = useState(null);

const handleFileChange = event => {
setSelectedFile(event.target.files[0]);
};

const handleUploadClick = async () => {
const formData = new FormData();
formData.append('file', selectedFile);
const response = await fetch('https://your-api-endpoint.com/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
console.log(data);
};

return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUploadClick}>Upload</button>
</div>
);
}

export default FileUpload;

Fetch Uploading a File with Progress in React

import React, { useState } from 'react';

function FileUpload() {
const [selectedFile, setSelectedFile] = useState(null);
const [uploadProgress, setUploadProgress] = useState(0);

const handleFileChange = event => {
setSelectedFile(event.target.files[0]);
};

const handleUploadClick = async () => {
const formData = new FormData();
formData.append('file', selectedFile);
const response = await fetch('https://your-api-endpoint.com/upload', {
method: 'POST',
body: formData,
onUploadProgress: progressEvent => {
const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
setUploadProgress(percent);
}
});
const data = await response.json();
console.log(data);
};

return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUploadClick}>Upload</button>
{uploadProgress > 0 && <div>Upload progress: {uploadProgress}%</div>}
</div>
);
}

export default FileUpload;

Fetch check if request successful

async function fetchData() {
try {
const response = await fetch('https://your-api-endpoint.com/data');
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}

fetchData();

Axios

Axios GET Async/Await

import axios from 'axios';

async function fetchData() {
try {
const response = await axios.get('https://your-api-endpoint.com/data');
console.log(response.data);
} catch (error) {
console.error(error);
}
}

fetchData();

Axios with TypeScript async/await

import axios, { AxiosResponse } from 'axios';

interface MyData {
id: number;
name: string;
}

const fetchData = async (): Promise<AxiosResponse<MyData>> => {
try {
const response = await axios.get<MyData>('/data');
return response;
} catch (error) {
console.error(error);
throw error;
}
};

fetchData().then(response => {
console.log(response.data);
});

Fetch API promises/then/catch

import axios from 'axios';

axios.get('https://your-api-endpoint.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});

Axios async/await POST body with error handling

import axios from 'axios';

async function postData() {
try {
const response = await axios.post('https://your-api-endpoint.com/data', {
data: 'example data',
});
console.log(response.data);
} catch (error) {
console.error(error);
}
}

postData();

Axios PATCH with Authorization token

import axios from 'axios';

const token = 'your-auth-token';

async function patchData() {
try {
const response = await axios.patch('https://your-api-endpoint.com/data', {
data: 'example data',
}, {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(response.data);
} catch (error) {
console.error(error);
}
}

patchData();

Axios with extra options


import axios from 'axios';

const config = {
method: 'get',
url: 'https://your-api-endpoint.com/data',
headers: {
'Content-Type': 'application/json',
},
params: {
id: 1,
},
timeout: 5000,
};

axios(config)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});

Axios with custom headers, AWS API key and retry

import axios from 'axios';
import axiosRetry from 'axios-retry';

const apiKey = 'your-api-key';

const config = {
method: 'get',
url: 'https://your-api-endpoint.com/data',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
},
params: {
id: 1,
},
};

async function fetchData() {
axiosRetry(axios, {
retries: 3,
retryCondition: error => error.response.status === 503,
});

try {
const response = await axios(config);
console.log(response.data);
} catch (error) {
console.error(error);
}
}

fetchData();

Axios set default request headers for all requests:

axios.defaults.headers.common['Authorization'] = 'Bearer your-token';

Axios send FormData with the FormData API


const formData = new FormData();
formData.append('username', 'example');
formData.append('password', '123456');

axios.post('/login', formData);

Axios Intercept requests and responses with middleware:

axios.interceptors.request.use(config => {
// Do something with request config
return config;
}, error => {
// Do something with request error
return Promise.reject(error);
});

axios.interceptors.response.use(response => {
// Do something with response data
return response;
}, error => {
// Do something with response error
return Promise.reject(error);
});

Cancel requests with a cancel token

const source = axios.CancelToken.source();

axios.get('/data', {
cancelToken: source.token,
});

// Cancel the request
source.cancel('Request cancelled');

Use axios.all() to make multiple requests and wait for completion

axios.all([
axios.get('/data1'),
axios.get('/data2'),
axios.get('/data3'),
])
.then(axios.spread((response1, response2, response3) => {
// Do something with all responses
}))
.catch(error => {
console.error(error);
});

Axios cancel requests when component unmounts

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const MyComponent = () => {
const [data, setData] = useState(null);
const source = axios.CancelToken.source();

useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get('/data', {
cancelToken: source.token,
});
setData(response.data);
} catch (error) {
if (axios.isCancel(error)) {
console.log('Request cancelled');
} else {
console.error(error);
}
}
};

fetchData();

return () => {
source.cancel('Request cancelled');
};
}, []);

return (
// Component code
);
};

Axios getUri() to get the full URL of a request

const config = {
method: 'get',
url: '/data',
params: {
id: 1,
},
};

const uri = axios.getUri(config);
console.log(uri); // Output: "/data?id=1"

Axios file uploading with progress

import React, { useState } from 'react';
import axios from 'axios';

const FileUpload = () => {
const [selectedFile, setSelectedFile] = useState(null);
const [uploadProgress, setUploadProgress] = useState(0);

const handleFileChange = event => {
setSelectedFile(event.target.files[0]);
};

const handleFileUpload = async () => {
const formData = new FormData();
formData.append('file', selectedFile);

try {
const response = await axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: progressEvent => {
setUploadProgress(Math.round((progressEvent.loaded * 100) / progressEvent.total));
},
});

console.log(response.data);
} catch (error) {
console.error(error);
}
};

return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleFileUpload}>Upload File</button>
<div>Progress: {uploadProgress}%</div>
</div>
);
};

Tanstack React Query

React Query query, useQuery with Typescript

import { useQuery } from 'react-query';

interface Todo {
userId: number;
id: number;
title: string;
completed: boolean;
}

const getTodo = async (): Promise<Todo> => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
return data;
};

const Todo = () => {
const { data, isLoading, isError, error } = useQuery<Todo, Error>('todo', getTodo);

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

return (
<div>
<h1>Todo</h1>
<p>{data?.title}</p>
</div>
);
};

export default Todo;


React Query mutation (ie. PATCH)) with Typescript

import { useMutation } from 'react-query';

interface Todo {
userId: number;
id: number;
title: string;
completed: boolean;
}

const updateTodo = async (id: number, token: string, data: Partial<Todo>) => {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error('Network response was not ok');
}
const responseData = await response.json();
return responseData;
};

const TodoForm = () => {
const [title, setTitle] = useState('');
const [completed, setCompleted] = useState(false);
const { mutate, isLoading, isError, error } = useMutation<Todo, Error, { id: number; token: string; data: Partial<Todo> }>(
({ id, token, data }) => updateTodo(id, token, data),
);

const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
mutate({ id: 1, token: 'my-auth-token', data: { title, completed } });
};

return (
<form onSubmit={handleSubmit}>
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
<input type="checkbox" checked={completed} onChange={(e) => setCompleted(e.target.checked)} />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Update'}
</button>
{isError && <div>Error: {error?.message}</div>}
</form>
);
};

export default TodoForm;

RTK Query

RTK Query async/await with Typescript

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

interface Todo {
userId: number;
id: number;
title: string;
completed: boolean;
}

interface GetTodoResponse {
data: Todo;
error: string | null;
}

const api = createApi({
reducerPath: 'todoApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com' }),
endpoints: (builder) => ({
getTodo: builder.query<GetTodoResponse, void>({
query: () => '/todos/1',
}),
}),
});

export const { useGetTodoQuery } = api;

RTK Query mutation (ie. PATCH)) with Typescript

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import type { Todo } from './types';

interface UpdateTodoData {
id: number;
token: string;
data: Partial<Todo>;
}

export const todoApi = createApi({
reducerPath: 'todoApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com' }),
endpoints: (builder) => ({
updateTodo: builder.mutation<Todo, UpdateTodoData>({
query: ({ id, token, data }) => ({
url: `/todos/${id}`,
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: data,
}),
}),
}),
});

export const { useUpdateTodoMutation } = todoApi;

Apollo Client

Apollo Client query, useQuery with Typescript


import React from 'react';
import { useQuery, gql } from '@apollo/client';

interface Book {
title: string;
author: string;
}

interface BooksData {
books: Book[];
}

const GET_BOOKS = gql`
query GetBooks {
books {
title
author
}
}
`;

const BookList = () => {
const { loading, error, data } = useQuery<BooksData>(GET_BOOKS);

if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;

return (
<ul>
{data?.books.map(book => (
<li key={book.title}>
<strong>{book.title}</strong> by {book.author}
</li>
))}
</ul>
);
};

export default BookList;

Apollo Client mutation with Typescript

import { useMutation, gql } from '@apollo/client';
import type { Todo } from './types';

const UPDATE_TODO = gql`
mutation UpdateTodo($id: ID!, $data: TodoInput!) {
updateTodo(id: $id, data: $data) {
id
title
completed
}
}
`;

interface UpdateTodoData {
id: string;
data: Partial<Todo>;
}

export const UpdateTodoMutation = () => {
const [updateTodo, { loading, error }] = useMutation<{ updateTodo: Todo }, UpdateTodoData>(UPDATE_TODO);

const handleUpdateTodo = async (id: string, data: Partial<Todo>) => {
try {
const { data: response } = await updateTodo({ variables: { id, data } });
console.log(response.updateTodo);
} catch (err) {
console.error(err);
}
};

return (
<button onClick={() => handleUpdateTodo('1', { completed: true })}>
{loading ? 'Updating...' : 'Update Todo'}
</button>
);
};

Apollo Client mutation with Typescript and optimistic response

import { useMutation, gql } from '@apollo/client';
import type { Todo } from './types';

const UPDATE_TODO = gql`
mutation UpdateTodoMutation($id: ID!, $completed: Boolean!) {
updateTodo(
id: $id,
data: {
completed: $completed
}
) {
id
title
completed
}
}
`;

interface UpdateTodoMutationResponse {
updateTodo: Todo;
}

interface UpdateTodoMutationVariables {
id: string;
completed: boolean;
}

export const UpdateTodoMutation = ({ id, completed }: UpdateTodoMutationVariables) => {
const [updateTodo, { loading, error }] = useMutation<UpdateTodoMutationResponse, UpdateTodoMutationVariables>(UPDATE_TODO, {
context: {
headers: {
authorization: `Bearer ${process.env.AUTH_TOKEN}`
}
}
});

const handleUpdateTodo = async () => {
try {
const { data } = await updateTodo({
variables: {
id,
completed
}
});

console.log(data.updateTodo);
} catch (error) {
console.error(error);
}
};

return (
<button onClick={handleUpdateTodo}>
{loading ? 'Updating...' : 'Update Todo'}
</button>
);
};

Apollo Client mutation with Typescript, auth and


import { useMutation, gql } from '@apollo/client';
import type { Todo } from './types';

const UPDATE_TODO = gql`
mutation UpdateTodoMutation($id: ID!, $completed: Boolean!) {
updateTodo(
id: $id,
data: {
completed: $completed
}
) {
id
title
completed
}
}
`;

interface UpdateTodoMutationResponse {
updateTodo: Todo;
}

interface UpdateTodoMutationVariables {
id: string;
completed: boolean;
}

export const UpdateTodoMutation = ({ id, completed }: UpdateTodoMutationVariables) => {
const [updateTodo, { loading, error }] = useMutation<UpdateTodoMutationResponse, UpdateTodoMutationVariables>(UPDATE_TODO, {
context: {
headers: {
authorization: `Bearer ${process.env.AUTH_TOKEN}`
}
},
fetchPolicy: 'cache-and-network',
errorPolicy: 'all',
retry: {
max: 3,
delay: 1000,
attempts: (count, operation, error) => {
console.log(`Retry attempt ${count}: ${error?.message}`);
return true;
},
},
});

const handleUpdateTodo = async () => {
try {
const { data } = await updateTodo({
variables: {
id,
completed
}
});

console.log(data.updateTodo);
} catch (error) {
console.error(error);
}
};

return (
<button onClick={handleUpdateTodo}>
{loading ? 'Updating...' : 'Update Todo'}
</button>
);
};