Im making a project where I fetch an image of a recipe card from https://spoonacular.com and I want it displayed on my react.js app. For some reason I can't get the API data from displaying on the page when I run it. Please help Im really stuck. I keep getting the error that recipeList is undefined in Recipe.js but I thought it was defined?
This is my Home.js:
import React, { useEffect, useState } from "react";
import axios from "axios";
import Recipe from "../components/Recipes";
const URL = `https://api.spoonacular.com/recipes/716429/information?apiKey=${APIKey}&includeNutrition=false`;
function Home() {
const [food, setFood] = useState();
useEffect(() => {
if (food) {
axios
.get(URL)
.then(function (response) {
const recipeList = response.data;
setFood(recipeList);
})
.catch(function (error) {
console.warn(error);
});
}
}, [food]);
return (
<main>
<Recipe recipeList={food} />
</main>
);
}
export default Home;
this is my Recipe.js
import React from "react";
function Recipe({ recipeList }) {
return (
<div className="Recipe">
<div>{recipeList.title}</div>
<img src={recipeList.image} />
</div>
);
}
export default Recipe;
you need initializing empty
const [food, setFood] = useState({});
and in useEffect evaluate if food is empty
useEffect(() => {
const getData=()=>{
axios
.get(URL)
.then(function (response) {
const {data} = response;
setFood(data);
})
.catch(function (error) {
console.warn(error);
});
}
if(!food){ // validate if food is empthy to get data (food)
getData()
}
}, []); // here is not necesary use food, because never happen anything with that variable
The response example can be seen here.
To call that using axios:
import React, { useEffect, useState } from "react";
import axios from "axios";
import Recipe from "../components/Recipes";
const URL = `https://api.spoonacular.com/recipes/716429/information?apiKey=${APIKey}&includeNutrition=false`;
function Home() {
const [food, setFood] = useState({});
useEffect(() => {
// You can add any if-else statement here
// but you can also do the fetch without it
axios
.get(URL)
.then(function (response) {
setFood(response.data);
})
.catch(function (error) {
console.warn(error);
});
}, []);
return (
<main>
<Recipe recipeList={food} />
</main>
);
}
export default Home;
And based on the response, your Recipe.js should working properly.
Related
I'm in the process of building a merch e-commerce website for a client utilizing the commerce.js API however I've run into a problem. When passing the "cart" object as a prop to the checkout file it returns as an empty object which breaks the website. The web application passes the "cart" object as a prop in other parts of the code and works just fine. Is there something I'm doing wrong?
Code for reference:
import React, { useState, useEffect } from 'react';
import {Paper, Stepper, Step, StepLabel, Typography, CircularProgress, Divider, Button} from '#material-ui/core';
import { commerce } from '../../../lib/commerce';
import Addressform from '../Addressform';
import Paymentform from '../Paymentform';
const steps =['Shipping Address', 'Payment details'];
const Checkout = ({ cart }) => {
const [activeStep, setActiveStep] = useState(0);
const [checkoutToken, setCheckoutToken] = useState(null);
useEffect (() => {
const generateToken = async () => {
console.log(cart.id);
// returns as undefined
try {
const token = await commerce.checkout.generateToken(cart.id, { type: 'cart' });
console.log(token);
setCheckoutToken(token);
console.log("Success!")
} catch (error) {
console.log(error); //Returns 404 Error Obv
console.log("Didnt work")
}
}
generateToken();
}, []);
const Confirmation = () => (
<>
Confirmation
</>
);
const Form = () => activeStep === 0
? <Addressform />
: < Paymentform />
return(
<>
...
</>
);
};
export default Checkout;
Quick Help Needed! I have Two React components Vendors and VendorsList. In Vendors.js Component i have asset.asset_name text rendered in table format. What I want is, When I click on I asset.asset_name, I wanted to pass it's value from Vendors component to VendorsList component. How could I do this?
Here is code for Two Components
Vendors.js
import React, { useEffect, useState } from "react";
import { axios } from "axios";
const Vendors = () => {
const [data, setData] = useState({});
const baseURL =
"http://127.0.0.1:8000/api/business_process/business-impact/business-assets-detail";
useEffect(() => {
axios
.get(baseURL)
.then((response) => {
setData(response.data);
})
.then(
(response) => {},
(err) => {
alert("No Data To Show");
}
)
.catch((err) => {
return false;
});
}, []);
const DisplayData = data.business_assets?.map((asset) => {
return (
<tr>
<td>{asset.business_assets}</td>
<td onClick={() => alert(asset.asset_name)}>{asset.asset_name}</td>
</tr>
);
});
return <div></div>;
};
export default Vendors;
Here is VendorsList.js
import React from "react";
const VendorsList = () => {
return (
<div>
<h1>{foo}</h1>
</div>
);
};
export default VendorsList;
I need asset.asset_name value to be passed to VendorsList when I click on asset.asset_name value from Vendors component
I don't think you're passing the asset_name into your VendorsList component at all. I think the quickest way is to directly render the VendorsList in your Vendors component by putting it in the return of your Vendors component. You would also need something to record what you have clicked so you can use another useState for this. Below is how you'd achieve this:
Modify your Vendor.js to look like this:
import React, { useEffect, useState } from "react";
import { axios } from "axios";
import VendorsList from '<path to your VendorList component>'
const Vendors = () => {
const [data, setData] = useState({});
const [clickedAsset, setClickedAsset] = useState()
const baseURL =
"http://127.0.0.1:8000/api/business_process/business-impact/business-assets-detail";
useEffect(() => {
axios
.get(baseURL)
.then((response) => {
setData(response.data);
})
.then(
(response) => {},
(err) => {
alert("No Data To Show");
}
)
.catch((err) => {
return false;
});
}, []);
const DisplayData = data.business_assets?.map((asset) => {
return (
<tr>
<td>{asset.business_assets}</td>
<td onClick={() => setClickedAsset(asset.asset_name)}>{asset.asset_name}</td>
</tr>
);
});
return (
<div>
<DisplayData/>
<VendorList clickedAssetName={clickedAsset}/>
</div>
);
};
export default Vendors;
Then to use the clickedAssetName that you just passed, access it like this in your VendorsList.js component:
import React from "react";
const VendorsList = ({clickedAssetName}) => {
return (
<div>
<h1>{clickedAssetName}</h1>
</div>
);
};
export default VendorsList;
Im building a react app that fetches a random food data from spoonacular.com. Im trying to display the title name of the food on the page but it doesn't show up and also why does it keep fetching a bunch of different data as shown in the picture of the console.log even though I specified the number of data to fetch as 1 in the URL
This is my Home.js
import React, { useEffect, useState } from "react";
import axios from "axios";
import Recipe from "../components/Recipes";
const URL = `https://api.spoonacular.com/recipes/random?apiKey=${APIKey}&number=1`;
function Home() {
const [food, setFood] = useState({});
useEffect(() => {
axios
.get(URL)
.then(function (response) {
setFood(response.data);
console.log(food);
})
.catch(function (error) {
console.warn(error);
});
}, [food]);
return (
<main>
<Recipe recipeList={food} />
</main>
);
}
export default Home;
and this is my Recipe.js component
import React from "react";
function Recipe({ recipeList }) {
return (
<div className="recipeCard">
<h1>{recipeList.title}</h1>
</div>
);
}
export default Recipe;
and this is the picture of the console when I log the results fetched from the API (they're all different food datas but I only wanted to fetch 1 food data and display it on the page)
That's right, you get 1 random recipe, but useEffect works every time you update the food state, so you have an infinite loop. Just remove food from useEffect dependency. It's also better to check if recipeList exists so you don't get a missing title error
This should work as expected:
Home.js:
import React, { useEffect, useState } from "react";
import axios from "axios";
import Recipe from "../components/Recipes";
const URL = `https://api.spoonacular.com/recipes/random?apiKey=${APIKey}&number=1`;
function Home() {
const [food, setFood] = useState(null);
useEffect(() => {
axios
.get(URL)
.then(function (response) {
setFood(response.data);
console.log(food);
})
.catch(function (error) {
console.warn(error);
});
}, []);
return (
<main>
<Recipe recipeList={food} />
</main>
);
}
export default Home;
Recipe.js:
import React from "react";
function Recipe({ recipeList }) {
if(!recipeList) return <></>
return (
<div className="recipeCard">
<h1>{recipeList?.title}</h1>
</div>
);
}
export default Recipe;
Im building an app where I want to take api data from https://www.thecocktaildb.com to allow for users to search for a cocktail drink and it will fetch data from the api source to display the name of the drink on the page. I don't know why its giving me an error of "Uncaught TypeError: drinkList.drinks is undefined" because if you look at the screenshot I included of what the JSON data looks like, it should be correct?
This is my Home.js
import React, { useEffect, useState } from "react";
import axios from "axios";
import Drinks from "../components/Drinks";
function Home() {
const [drinkName, setDrinkName] = useState();
const drinksURL = `https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${drinkName}`;
function handleChangeDrink(e) {
setDrinkName(e.target.value);
}
const getDrink = () => {
axios
.get(drinksURL)
.then(function (response) {
setDrinkName(response.data);
console.log(drinksURL);
})
.catch(function (error) {
console.warn(error);
});
};
return (
<main className="App">
<section className="drinks-section">
<input
type="text"
placeholder="Name of drink (e.g. margarita)"
onChange={handleChangeDrink}
/>
<button onClick={getDrink}>Get a Drink Recipe</button>
<Drinks drinkList={drinkName} />
</section>
</main>
);
}
export default Home;
and this is my Drinks.js component
import React from "react";
function Drinks({ drinkList }) {
if (!drinkList) return <></>;
return (
<section className="drinkCard">
<h1>{drinkList.drinks[0].strDrink}</h1>
</section>
);
}
export default Drinks;
This is a screenshot of the JSON data:
You should define the new variable for drink list
const [drinkList, setDrinkList] = useState([]);
And you should assign your response to this variable here (instead of assigning drinkName):
const getDrink = () => {
axios
.get(drinksURL)
.then(function (response) {
setDrinkList(response.data);
console.log(drinksURL);
})
.catch(function (error) {
console.warn(error);
});
};
Goal: Fetch data from api then assign it to a state for further processing.
Issue: After setting the data to my useState it is still undefined.
Questions:
How would one solve this problem?
Am I misunderstanding the useState hook?
import "./styles.css";
import axios from "axios";
import { useEffect, useState } from "react";
export default function App() {
const [userData, setUserData] = useState();
const functionz = () => {
return axios
.get("https://randomuser.me/api/")
.then(({ data }) => data.results);
};
useEffect(async () => {
const data = await functionz();
setUserData(data);
}, []);
if (userData) {
console.log(userData);
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Edit to see some magic happen!</h2>
</div>
);
}
You have to make sure your function is returning the axios call. Then await whatever comes out of it in your useEffect. Then proceed to adding it to your state. See example.
import React, { useState, useEffect } from 'react'
import axios from "axios";
const Api = () => {
const [usersData, setUsersData] = useState(null)
const fetchRandomUserData = () => axios.get('the-url')
useEffect(() => {
fetchRandomUserData()
.then(resp => {
setUsersData(resp.data.results)
})
.catch(e => {
console.log('Error: ', e)
})
}, [])
console.log(usersData)
return <div></div>
}
export default Api