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;
Related
Hi All i am trying to use graphql api to fetch some country. I am using this API https://studio.apollographql.com/public/countries/home?variant=current and this is playground https://countries.trevorblades.com/
The problem i am facing is that i cannot resolve the Promise. I am using React and fetch method.
my fetchCountries.js file:
import { API_URL } from "./constants";
const COUNTRIES_QUERY = `{
country(code: "BR") {
name
native
emoji
currency
languages {
code
name
}
}
}`;
const fetchCountries = async () => {
await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: COUNTRIES_QUERY,
}),
})
.then((response) => {
if (response.status >= 400) {
throw new Error("Error fetching data");
} else {
return response.json();
}
})
.then((data) => data.data);
};
export default fetchCountries;
i am using async, await in the function so that it gets resolved when i call it. Now in my App.js when i call fetchCountries function in console.log i get :
Promise {<pending>}
[[Prototype]]
:
Promise
[[PromiseState]]
:
"fulfilled"
[[PromiseResult]]
:
undefined
App.js:
import "./App.css";
import fetchCountries from "./api/fetchCountries";
const App = () => {
console.log("CONSOLE LOG API", fetchCountries());
return <div>App</div>;
};
export default App;
I have also tried to use useEffect hook but got the same result:
import "./App.css";
import fetchCountries from "./api/fetchCountries";
import React, { useEffect, useState } from "react";
const App = () => {
const [test, setTest] = useState();
console.log("CONSOLE LOG API", fetchCountries());
useEffect(() => {
const getCountries = async () => {
await fetchCountries();
};
setTest(getCountries());
}, []);
console.log("USE EFFECT API", test);
return <div>App</div>;
};
export default App;
You should do it as follows
const fetchCountries = async () => {
const response = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: COUNTRIES_QUERY,
}),
})
if (response.status >= 400) {
throw new Error("Error fetching data");
} else {
return await response.json();
}
};
export default fetchCountries;
Or enclose entire fetch.then... chain inside paranthesis.
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.
On a vue application, on a component, calling API to get some data... the problem is that getting undefined, before the call ends... Possible needed aync/await but getting error when adding
//component code (login.vue)
import store from "#/store";
const { response, error } = store.postTO(url, [{id: "button1"}, {id: "button2"}, {id: "button3"}]);
if (response) {
console.log(response);
} else {
console.warn(error);
}
//store.js
export default {
user : null,
postTO
}
function postTO(url, postData) {
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: JSON.stringify(postData)
};
return fetch(url, requestOptions).then(response =>
response.json().then(data => ({
data: data,
status: response.status
})
).then(res => {
console.log(res.data);
return {response : res.data, error : "test"};
}))
.catch(error => {
return {response : "test", error : error};
});
}
illustrated
In the component you have to wait for the fetch by putting an await before the store.posTo
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 } };
};