Receiving undefined instead of JSON - reactjs

I am using React axios to receive the JSON (array of objects) from server (server side is written on Go, I checked via Postman, JSON is sent properly).
Here is how I get the data on client side:
export const getPostData = async () => {
const URL = 'http://localhost:8083/test'
try {
const { data: { data }} = await axios.get(URL);
console.log(data)
return data;
} catch (error) {
console.log(error)
}
};
And this is how the getPostData is called in App.js:
const App = () => {
const [ posts, setPosts ] = useState([]);
useEffect(() => {
getPostData()
.then((data) => {
setPosts(data)
console.log(data)
})
},[]);
The problem is I get undefined in browser console. I found many similar questions asked here, but I could not find the solution (the Access-Control-Allow-Origin header is set when I send the JSON).
What should I learn more, where could be the problem? I would be very grateful for any help!
If this could be helpful, here is how I send the JSON in Go:
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Content-Type", "application/json")
c.JSON(http.StatusOK, gin.H{
"message": "Hello",
})

This looks suspect:
const { data: { data }} = await axios.get(URL);
That tries to read a property called data from an object on the data property of the response from axios, like this without the destructuring:
const data = (await axios.get(URL)).data.data;
Your Go code doesn't look like it puts a {"data": ___} wrapper around what it sends, and Axios only adds one layer of {data: ___} wrapper to what it gives you in the response, not two.
If you want the object from the JSON response, remove the inner destructuring:
const { data } = await axios.get(URL);
data will be {message: "Hello"} assuming the Go code sends the JSON {"message": "Hello"}.
Separately, your JavaScript code seems to expect an array of posts, but your Go code is just sending {"message": "Hello"}.

Related

res.json not working correctly with axios / React

What I want to do :
I send the GET request through axios
I open a local Json file with fs.readfile
I process the data and return it
I want to display the data when it return with res.json
what actually happened
I send the GET request through axios
I open a local Json file with fs.readfile
They return the data before fs.readfile finished so it's undefined or blank
This one I put on the frontend and the controller
//frontend
const fetchRewards = async()=>{
let link ="/api/reward";
const {data} = await axios.get(link);
console.log(data); **// this one logging undefined**
}
// on controller
async getRewardsById(req,res,next) {
try {
const result = await rewardService.getReward();
res.json(result);
} catch (error) {
next(error);
}
},
This is my service
const getReward = async () => {
fs.readFile("test.json", (err, inputData) => {
return {"name":"John", "age":30, "car":null};
}
console.log("done");
}
Seems to me like you are not returning anything from your service?
Try returning the fs.readFile.

Why do I keep getting Syntax Error: JSON parse even though my code works with another API?

Working with React and I continually get a SyntaxError:JSON.parse when I try to fetch from the API. I'm able to fetch the data just fine when working with a different API.
What am I doing wrong here? I'm a complete newb when it comes to API's so please don't eviscerate me if this is a stupid question :D
const API_URL = 'www.themealdb.com/api/json/v1/1/search.php?s=Arrabiata';
const getMealRequest = async()=>{
const response = await fetch(API_URL)
const data = await response.json()
console.log(data)
}
useEffect(()=>{
getMealRequest()
},[])
There is an error on your API call which is not related to this question. You didn't implement try/cath block with the getMealRequest so in the failure case, the response is not a valid object to parse and you get the mentioned error.
To solve it:
const getMealRequest = async () => {
try {
const response = await fetch('https://www.themealdb.com/api/json/v1/1/search.php?s=Arrabiata'
)
const data = await response.json()
console.log(data)
} catch (error) {
console.log(error)
}
}
Now inspect your console and see what is wrong with your API call. also, you can check the network tab for further detail about the request and response on calling API_URL.
const API_URL = 'https://www.themealdb.com/api/json/v1/1/search.php?s=Arrabiata';
const getMealRequest = async() => {
const response = await fetch(API_URL)
const data = await response.json()
console.log(data)
}
getMealRequest()
You forgot to include protocol:
incude https:// before the address and it will work:

Parse Nested JSON Using Axios and Async/Await

I am trying to fetch data from an api which should return a json object with an array of recipes. I am using React hooks on the front end and Axios to perform the request. The hook runs but I get an error while trying to access the json array from the response.
Here's the sample api response:
{
count: 30,
recipes: [objects, ... 29]
}
and my code to get the recipe response:
const fetchRecipes = async () => {
try {
const recipeData = await Axios.get(api);
console.log(recipeData);
const recipes = await recipeData.json(); // error occurs here
setRecipes(recipes);
setLoading(false);
} catch (err) {
console.log(`Error occurred fetching recipes ${err}`)
}
};
useEffect(() => {
fetchRecipes();
}, []);
I have removed the hooks declarations and api url is https://api.myjson.com/bins/t7szj. The problem lies in getting the array from the response. Is there something wrong with my api call?
This is the error message:
Error occurred fetching recipes TypeError: recipeData.json is not a function
Did you try this?
const fetchRecipes = async () => {
try {
const recipeData = await Axios.get(api);
console.log(recipeData.data);
const recipes = recipeData.data;
setRecipes(recipes);
setLoading(false);
} catch (err) {
console.log(`Error occurred fetching recipes ${err}`)
}
};
you don't have to call res.json() on the response when using axios (unlike fetch) because axios handles that for you automatically. Meaning that axios parses the response to JSON by default.
async/await with Axios

Firebase returning two different outputs

I've made a simple class that returns the data downloaded from firebase. The issue is that if I console.log data in the class, it gives data as expected. However, if I import this class anywhere else and try to use it, it returns data as undefined.
Can you explain what's wrong?
My getCollection func in class dbAPI (data is correct)
getCollection(collection) {
dataBase
.collection(collection)
.get()
.then(querySnapshot => {
let data = querySnapshot.docs.map(doc => doc.data())
console.log(data)
return data
})
.catch(function(error) {})
}
The way I try to get data (data is undefined here)
componentDidMount() {
const db = new dbAPI()
let data = db.getCollection("collectionName")
this.setState({ data })}
The issue is that you're trying to return data from a callback to a synchronous function, which is impossible (link). You need to either promisify your getCollection function, or use async/await. If you want to convert your code to use async/await, check out this link. I put an example below. Basically, you need to await for the get request to get the data, then perform your transformation. After performing that transformation, you can return data.
async getCollection(collection) {
const collectionRef = dataBase.collection(collection);
try {
const dataSnapshot = await collectionRef.get();
const data = querySnapshot.docs.map(doc => doc.data());
console.log(data);
return data;
} catch (err) {
console.log(err);
}
}
In your componentDidMount, you must add async/await keywords to the appropriate functions. Async needs to go to the top to mark componentDidMount as async, and you need to await the data from the function call db.getCollection.
async componentDidMount() {
const db = new dbAPI()
const data = await db.getCollection("collectionName")
this.setState({ data })
}
Thanks to you I've managed to do it, really appreaciate your help, my solution:
getCollection:
async getCollection(collection) {
let data = null
await dataBase
.collection(collection)
.get()
.then(querySnapshot => {
data = querySnapshot.docs.map(doc => doc.data())
})
.catch(function(error) {
console.error(`Data fetch failed: \n${error}`)
data = "ERROR"
})
return data}
getting data:
async componentDidMount() {
const db = new Database()
const data = await db.getCollection("collectionName")
this.setState({ ...data })}

Send array from React to Express/Node to query Mongo

I am having difficulty sending an array of Id numbers from React state, through Node/Express, then eventually to MongoDB.
The main difficulty is how to send an array from React to the server. Once I have it there in a usable array form, I believe I know how to query MongoDB using an array.
I have been trying to do this mainly with a GET method and have been unsuccessful using req.params or req.query. I have tried this with several versions of string templates, and using what the Axios docs say as well as many other answers on stack overflow, none have been successful.
I have also tried a couple of versions of a PUT request and also with no success.
The array of Ids already exists in props.completedJobs:
In React:
useEffect(() => {
const fetchData = async () => {
let completedJobsArray = props.completedJobs;
let json = JSON.stringify(data);
let getData = {jsonData: json};
const result = await axios('/api/brief/brief-array/' + getData);
setData(result.data);
};
fetchData();
}, []);
In Express app:
app.use("/brief", briefRouter);
then in the router:
router.get("/brief-array/:briefArray", briefController.brief_findArrayById);
then the function:
exports.brief_findArrayById = async (req, res) => {
try {
// console.log("req.body: ", req.body);
// console.log("req: ", req);
// console.log("req.query: ", req.query);
// console.log("req.params: ", JSON.stringify(req.params.briefArray));
const briefs = await GWJob.find({"_id": {$in: ["5d1297512c68bc49060bce7b", "5d1297092c68bc49060bce7a"] } });
res.json(briefs);
} catch (err) {
res.json({ message: err });
}
}
The MongoDB query works with the hard-coded IDs, but cannot get any of the above versions of console.logs to display any value other than undefined or "object object".
I am also unable to query the database using an array through Postman.
I expect to send 1 or more id numbers in an array to MongoDB, and receive those documents back to React on the front end. Any help with sending an array from state in React through Node/Express is much appreciated! Thank you.
You are sending Long string through the URL which is a limited length (~2047 char),
the safe away to accomplish what you are trying to do to use a post or put method and send the list in the body.
Example:
useEffect(() => {
const fetchData = async () => {
let completedJobsArray = props.completedJobs;
const result = await axios({
method: 'post',
url: '/brief-array',
data: completedJobsArray
});
setData(result.data);
};
fetchData();
}, []);
Another attempt, still returning undefined. If anyone has links to a thorough resource on sending/receiving data I would much appreciate it. I always have spent days trying to get one of these to work, until I started using Axios, but if I need to go beyond what I can do with Axios I am back to square one. Many thanks.
useEffect(() => {
const fetchData = async () => {
let completedJobsArray = props.completedJobs;
let queryData = {completedJobsArray};
const settings = {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=utf-8'},
body: JSON.stringify(queryData)
};
try {
const fetchResponse = await fetch(`/api/brief/brief-array`, settings);
const returnedData = await fetchResponse.json();
setData(returnedData);
} catch (error) {
console.error("error: ", error);
}
}
fetchData();
}, []);

Resources