NextJS: Axios does not decode data value on the server side - reactjs

When I try to use Axios in serverSideProps I get a strange data value, at first, I thought it was a Redux issue, but no, if I replace Axios with Fetch everything works correctly. Outside of serverSideProps Axios also works well.
export async function getServerSideProps() {
const res = await axios.get(
`https://jsonplaceholder.typicode.com/posts/`
);
console.log(res.data);
// const res = await fetch(`https://jsonplaceholder.typicode.com/posts/`);
// console.log(await res.json());
return {
props: {}
};
}
value I get
codeSandbox example

The problem is with axios v1.2.0 itself. You need to add Accept and Accept-Encoding headers as a temporary solution until the issue is solved:
const res = await axios.get('https://jsonplaceholder.typicode.com/posts', {
headers: {
Accept: 'application/json',
'Accept-Encoding': 'identity'
}
})
Github discussion about this problem.

It's a bug in Axios - I think dealing with gzip encoding. You can see the issue here.
Workaround:
import { createAsyncThunk } from "#reduxjs/toolkit";
import axios from "axios";
export const fetchJob = createAsyncThunk(
"users/fetchJobs",
async () => {
const res = await axios.get("https://jsonplaceholder.typicode.com/posts", {
headers: { Accept: "application/json", "Accept-Encoding": "identity" }
});
const data = res.data;
// const res = await fetch(`https://jsonplaceholder.typicode.com/posts`);
// const data = await res.json();
console.log(res);
return data;
}
);

Related

NextJS API Endpoint Error - 'API resolved without sending a response for /api/foo, this may result in stalled requests.'

This is the code I am using
// function calling the api endpoint within a button onClick event handler
async () => {
const response = await fetch('/api/foo', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
const responseData = await response.json()
}
// /api/foo.js
import { ref, uploadString } from 'firebase/storage'
import { storage } from './firebase'
export default async function handler(req, res) {
const data = req.body
const storageRef = ref(storage, data.ID)
const uploadTask = uploadString(storageRef,
JSON.stringify(data.object)
).then(snapshot => {
res.status(200).json(
{ message: 'Saved!', severity: 'success' })
res.end()
}
)
}
When a request is sent to the above API endpoint, the console in vscode shows that a request was sent with this error: API resolved without sending a response for /api/foo, this may result in stalled requests.
What does this mean and how is it fixed?
Thanks in advance!
Edit - added async to handler function, but error still showing

Using Axios in useEffect from an external file

I'm trying to export an axios call from an external file to my component, in useEffect. Im exporting the function and importing in the said component. The response is "undefined".
api_call.js:
import axios from 'axios';
const accessToken = window.localStorage.getItem('accessToken')
export const getPublicCircles = async () => {
const headers = {
'Content-Type': 'application/json',
'Accept-Language': 'fr',
'Authorization': `Bearer ${accessToken}`,
}
await axios.get('https://myurl.com/api/this-info', { headers })
.then(response => console.log(response))
.catch(error => console.log('error', error))
};
( I also tried with .then((response) => return response.data.data)
component.js
import * as API from '../../api/api_call';
export default function PublicCircles() {
const [circles, getCircles] = useState('');
useEffect(() => {
const fetchData = async () => {
const response = await API.getPublicCircles();
const json = await response.json();
console.log(response)
getCircles(response);
}
fetchData()
.catch(console.error);;
}, []);
return (
<Box>
{circles === '' ? null :
<PublicCircle circles={circles} />}
</Box>
)
}
Here are the results (getting the info from the api_call.js file, not the PublicCirlces.js one.
Thank you.
The real problem here is that the function getPublicCircles returns nothing, which is why any variable to which the result of this function call is assigned as a value, will be undefined per JavaScript rules, because a function that doesn't return any value will return undefined.
It's not a good idea to use async/await and then/catch in handling a promise together. Below is the example of handling it correctly with try/catch and async/await:
export const getPublicCircles = async () => {
const headers = {
'Content-Type': 'application/json',
'Accept-Language': 'fr',
'Authorization': `Bearer ${accessToken}`,
}
try {
const data = await axios.get('https://myurl.com/api/this-info', { headers });
return data;
} catch(error) {
console.error('error',error);
}
}

How do I make a PUT request with axios?

I'm trying to update a field on my MongoDB database with Axios PUT method in React JS. I'm also using react form hook.
const onSubmit = async itemData => {
console.log(itemData);
const url = `http://localhost:5000/items/${id}`
const { data } = await axios.put(url, {
productQTY: itemData.productQTY,
headers: {
authorization: `Bearer ${localStorage.getItem('accessKey')}`
}
})
so I can access itemData.productQTY from itemData. There is also a field in the Database named productQTY, so how do I update the field?
const onSubmit = async itemData => {
console.log(itemData);
const url = `http://localhost:5000/items/${id}`
const { data } = await axios.put(url,
{ productQTY: itemData.productQTY },
{
headers:
{
authorization: `Bearer ${localStorage.getItem('accessKey')}`
}
}
})
u can try it, with data and header in 2 params of put request.

I am trying to fetch users using Github API, but it says the token is wrong

I am try to fetch users information using github API
import React, { useEffect } from "react";
function UserResults() {
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
const response = await fetch(`${process.env.REACT_APP_GITHUB_URL}/users`, {
headers: {
Authorization: `token ${process.env.REACT_APP_GITHUB_TOKEN}`,
},
});
const data = response.json();
};
return <div>Hello</div>;
}
export default UserResults;
And here is what I put in my env:
REACT_APP_GITHUB_TOKEN="<token>"
REACT_APP_GITHUB_URL = "https://api.github.com"
I am sure the token is correctly generated and copied.
But it seems I can't fetch the data due to some "JSON" error as it shows in the console like this.
Can anyone offers any help with this?
You need to await response.json() and update your header request
import React, { useEffect } from "react";
function UserResults() {
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
const response = await fetch(`${process.env.REACT_APP_GITHUB_URL}/users`, {
headers: {
'Authorization': `token ${process.env.REACT_APP_GITHUB_TOKEN}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
});
const data = await response.json();
};
return <div>Hello</div>;
}
export default UserResults;

useSWR - How to pass config object to fetch

I'm trying to integrate useSWR in a next js project I'm working on.
I want to pass a config to fetcher as an argument. I have read about Multiple Arguments in the docs
but it's not returning the data for some reason. it is making the api request I can see that in the network tab.
not sure how to do this.
any suggestions?
const fetcher = async (url, config) => {
let res;
if (config) {
res = await fetch(url, config);
} else {
res = await fetch(url);
}
if (!res.ok) {
const error = new Error('An error occurred while fetching the data.');
error.info = await res.json();
error.status = res.status;
throw error;
}
return res.json();
};
const { data, error } = useSWR(
[
rolesUrl,
{
headers: {
Authorization: `Bearer ${user.token}`,
'Content-Type': 'application/json',
},
},
],
fetcher
);
After a very long debuging I found out. fetch is getting the config object.
and then makes the request to the api. then useSWR returns the response. which causes the component to re-render. the config object gets recreated.
useSWR thinks argument updated and make the api request again. that's why we don't get the data.
I have fixed this with useMemo hook
const config = useMemo(
() => ({
headers: {
Authorization: `Bearer ${user.token}`,
'Content-Type': 'application/json',
},
}),
[user.token]
);
const { data, error } = useSWR([rolesUrl, config], fetcher);

Resources