Data is returning undefine after they were fetched from the backend. When I console.log it, the data get returned in the console. But when I try to use the data, it was returning undefine
//Here is the my logic using axios but it didnot work, it keeps throwing 404 error and undefined data
import { createApi, fetchBaseQuery } from "#reduxjs/toolkit/query/react";
import axios from "axios";
const MyBaseQuery =
({ baseUrl } = { baseUrl: "http://localhost:5000" }) =>
async ({ url, method, data }) => {
try {
const result = await axios({ url: baseUrl + url, method, data });
return { data: result.data };
} catch (axiosError) {
let err = axiosError;
return {
error: { status: err.response?.status, data: err.response?.data },
};
}
};
export const getAllCarsApi = createApi({
reducerPath: "getAllCarsApi",
baseQuery: MyBaseQuery,
endpoints(build) {
return {
getAllCarsApi: build.query({
query: () => ({ url: "all-cars", method: "GET" }),
}),
};
},
});
export const { useGetAllCarsQuery } = getAllCarsApi;
I solve this by adding async and await in my functions.
Related
I'm trying to do a delete request. I can fetch the API route through pages/api/people/[something].js.
And this is the response I got from the browser's console.
DELETE - http://localhost:3000/api/people/6348053cad300ba679e8449c -
500 (Internal Server Error)
6348053cad300ba679e8449c is from the GET request at the start of the app.
In the Next.js docs, for example, the API route pages/api/post/[pid].js has the following code:
export default function handler(req, res) {
const { pid } = req.query
res.end(Post: ${pid})
}
Now, a request to /api/post/abc will respond with the text: Post: abc.
But from my API route pages/api/people/[something].js, something is undefined.
const { something } = req.query
UPDATED POST:
React component
export default function DatabaseTableContent(props) {
const id = props.item._id; // FROM A GET REQUEST
const hide = useWindowSize(639);
const [deletePeople] = useDeletePeopleMutation();
async function deleteHandler() {
await deletePeople(id);
}
return <Somecodes />;
}
apiSlice.js
export const apiSlice = createApi({
// reducerPath: "api",
baseQuery: fetchBaseQuery({ baseUrl: url }),
tagTypes: ["People"],
endpoints: (builder) => ({
getPeople: builder.query({
query: (people_id) => `/api/people/${people_id}`,
providesTags: ["People"],
}),
deletePeople: builder.mutation({
query: (studentInfo) => ({
url: `api/people/people-data/student-info/${studentInfo}`,
method: "DELETE",
headers: {
accept: "application/json",
},
}),
invalidatesTags: ["People"],
}),
}),
});
export const {
useGetPeopleQuery,
useDeletePeopleMutation,
} = apiSlice;
pages/api/people/people-data/student-info/[studentInfo].js
import { ObjectId, MongoClient } from "mongodb";
async function handler(res, req) {
const { studentInfo } = req.query; // the code stops here because "studentInfo" is undefined
const client = await MongoClient.connect(process.env.MONGODB_URI.toString());
const db = client.db("people-info");
if (req.method === "DELETE") {
try {
const deleteData = await db
.collection("student_info")
.deleteOne({ _id: ObjectId(studentInfo) });
const result = await res.json(deleteData);
client.close();
} catch (error) {
return res.status(500).json({ message: error });
}
}
}
export default handler;
The order of params passed to your handler functions needs to be reversed.
For NextJS API routes the req is the first param passed to the handler and the res param is second.
Example handler function from NextJS documentation:
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
I am trying to do a helper function to check if login or not in react and nodejs... in nodejs everything is fine but I have problems at reactside to get value outside of function with return:
return output always = undefined ...
Here is the function;
note: console.log (response) = {status: 200, data: true, error:
false}
import axios from "axios";
import { useState,useEffect } from 'react';
export const AuthController = (event) => {
let data = {data : localStorage.getItem("imtakilogintoken")}
async function getData() {
try {
let res = await axios({
url: 'http://localhost:3005/profile',
method: 'post',
timeout: 8000,
data :data,
headers: {
'Content-Type': 'application/json',
}
})
return {
status : res.status,
data : res.data,
error : false
}
}
catch (err) {
return {
status : false,
data : false,
error : err
}
}
}
var output;
useEffect(() => {
getData().then(response => {
console.log (response)
output = response;
})
}, []);
return output;
}
For your kind information useEffect() is async function, the control first going to return statement and at this time return output (undefined) having undefined.
I think here no need to wrap your function into useEffect() instead just return from then only. so code would look like below.
import axios from "axios";
import { useState,useEffect } from 'react';
export const AuthController = (event) => {
let data = {data : localStorage.getItem("imtakilogintoken")}
async function getData() {
try {
let res = await axios({
url: 'http://localhost:3005/profile',
method: 'post',
timeout: 8000,
data :data,
headers: {
'Content-Type': 'application/json',
}
})
return {
status : res.status,
data : res.data,
error : false
}
}
catch (err) {
return {
status : false,
data : false,
error : err
}
}
}
//var output;
getData().then(response => {
console.log (response)
return response;
}).catch(err=>{
return err;
})
}
I think the problem itself is how you are trying to reach the data, on react I will recommend you to create a custom hook that you can implement on any component that loads later on the app, something like this:
import { useState, useCallback } from "react";
import axios from "axios";
const useAuthControl = () => {
const [hasResponse, setResponse] = useState(null);
const getData = useCallback(
async (data) => {
try {
let res = await axios({
url: 'http://localhost:3005/profile',
method: 'post',
timeout: 8000,
data :data,
headers: {
'Content-Type': 'application/json',
}
})
setResponse({
status : res.status,
data : res.data,
error : false
})
}
catch (err) {
setResponse({
status : false,
data : false,
error : err
})
}
},
[]
);
return [getData, {hasResponse}];
};
export default useAuthControl;
I am trying to load items to my next.js page and it will fail:
import {getadminInfo} from '../../dataFetch/adminInfo'
import {addItem} from '../../dataFetch/catalog'
import {useState} from "react"
import { getList } from '../../dataFetch/catalogList'
export async function getStaticProps() {
const adminData = await getadminInfo()
const catlist = await getList()
return {
props: {
catlist,
adminData
}
}
}
export default function Main({allPostsData, adminData, catlist}) {
}
My function is :
export function getList() {
const pageInfo = {
page_size : "10",
page:"1"
}
const url = "http://localhost:8000/api/catalog/list?page_size="+pageInfo.page_size+"&page="+pageInfo.page;
try {
fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
fData=JSON.parse(JSON.stringify(data.response))
console.log("Returned catalog")
return fData
})
.catch(error => console.log(error))
} catch (err) {
console.log(err)
}
}
The API works and I get the right info back but I cannot load it to the page:
Error: Error serializing .catlist returned from getStaticProps in "/admin/main".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.
I found the issue. I did not implement the fetch correctly. It should have been async.
The reason I did not get the info is because nothing was returned.
I've this code into pages folder on my NextJS environment. It gets data calling an external API Rest, and it's working because the console.log(response); line show me by console the Json API response. The problem I've is that I get this error in browser:
TypeError: Cannot read property 'json' of undefined
Corresponding with this line code:
const data = await res.json();
This is the complete file with the code:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data Json: ", data);
return { props: { data } };
};
This is the Json API response that I see by console:
{
account: [
{
id: '7051321',
type: 'probe',
status: 'open',
newAccount: [Object],
lastDate: '2020-07-04',
taxExcluded: [Object],
totalRecover: [Object],
documentLinks: []
},
]
}
Any idea how can I solve it?
Thanks in advance.
UPDATE
Here the code working good:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try {
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data JSON: ", data);
return { props: { data } };
} catch (error) {
console.log("Data ERROR: ", error);
}
};
There are a couple of things you have to change.
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
return response; // 1. Add this line. You need to return the response.
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const data = await getFetch(invoicesUrl, params);
// const data = await res.json(); 2. Remove this you have already converted to JSON by calling .json in getFetch
console.log("Data Json: ", data); // Make sure this prints the data.
return { props: { data } };
};
You have return statement in wrong place.
When the function is expecting a return. You need to return when the statements are executed not inside the promise then function because it is an async callback function which is not sync with the statement inside getFetchfunction. I hope i have made things clear. Below is the code which will any how return something
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try{
const res = await getFetch(invoicesUrl, params);
console.log("Data Json: ", res);
}catch(error){
console.log("Data Json: ", error);
}
return { props: { res } };
};
I need to send an axios request passing a token, this token is saved on my AsyncStorage. The problem is, when i make the call looks like its been sended without the AsyncStorage return the token, also the then/catch do not trigger.
Code example:
export const verificarPreco = (produto, estabelecimento) => {
return async dispatch => {
axios({
method: "get",
url: `${API}preco/verificarPreco/?produto=${produto}&estabelecimento=${estabelecimento}`,
headers: {
"x-access-token": await AsyncStorage.getItem("#Offer4All:token")
}
})
.then(response => {
verificarPrecoSucesso(response.data, dispatch);
})
.catch(error => {
verificarPrecoErro(error.response, dispatch);
});
};
};
You could use just async/await instead of handling the promises manually, and putting a try/catch around that.
export const verificarPreco = (produto, estabelecimento) => {
return async dispatch => {
try {
const token = await AsyncStorage.getItem("#Offer4All:token");
const request = await axios({
method: "get",
url: `${API}preco/verificarPreco/?produto=${produto}&estabelecimento=${estabelecimento}`,
headers: {
"x-access-token": token
}
});
const response = await request.json();
verificarPrecoSucesso(response.data, dispatch);
} catch (error) {
verificarPrecoErro(error.response, dispatch);
}
};
};