this is the response from the API fetch
Object
0: {id: 'rec6d6T3q5EBIdCfD',
name: 'Best of Paris in 7 Days Tour',
info: 'Paris is synonymous with the finest things that cu…e vivre. Join us for the Best of Paris in 7 Days!',
image: 'https://dl.airtable.com/.attachments/a0cd0702c443f31526267f38ea5314a1/2447eb7a/paris.jpg', price: '1,995'}
1: {id: 'recIwxrvU9HfJR3B4',
name: 'Best of Ireland in 14 Days Tour',
info: "Rick Steves' Best of Ireland tour kicks off with t…eart. Join us for the Best of Ireland in 14 Days!",
image: 'https://dl.airtable.com/.attachments/6c24084000a3777064c5200a8c2ae931/04081a3e/ireland.jpeg', price: '3,895'}
2: {id: 'recJLWcHScdUtI3ny',
name: 'Best of Salzburg & Vienna in 8 Days Tour',
info: "Let's go where classical music, towering castles, … the Best of Munich, Salzburg & Vienna in 8 Days!",
image: 'https://dl.airtable.com/.attachments/27f6cbfe631e303f98b97e9dafacf25b/6bbe2a07/vienna.jpeg', price: '2,695'}
this is my react code the handleDelete function needs to delete the particular post clicked on i can do this if the response is an array of objects using the filter method but this is my first time working with object of objects
const url = "https://course-api.com/react-tours-project";
function Card() {
const handleDelete = (key) => {
}
const[isOpen,setisOpen]=useState(false)
const[response, setresponse]=useState(null)
useEffect(() => {
fetch(url)
.then(resp => resp.json())
.then((data) =>setresponse({...data}));
console.log(response)
}, [])
return (
<div className="section">{response ?
Object.keys(response).map((item, i) => (
<li className="travelcompany-input" key={i}>
<div className="single-tour">
<img src={response[item].image} alt="" />
<footer>
<div className="tour-info">
<h4>{response[item].name}</h4>
<div className="tour-price">
<h4>${response[item].price}</h4>
</div>
</div>
<div className="delete-btn" onClick={()=>handleDelete(key)}>Not Interested</div>
</footer>
</div>
</li>
))
:<h2>Loading...</h2>}
</div>
);
}
export default Card;
CodePudding user response:
1) You are getting an array of objects but you are converting into object as:
useEffect(() => {
fetch(url)
.then(resp => resp.json())
.then((data) => {
console.log(data); // array of objects
setresponse({...data}) // PROBLEM
});
You shouldn't use this
setresponse({...data});
instead you should use
setresponse(data);
Live Demo
2) You can create a loading
state as :
const [isLoading, setIsLoading] = useState(true);
and change it to false
in any case whethere the reqest is completed or not, So you can change state in finally
method of Promise
as:
useEffect(() => {
fetch(url)
.then((resp) => resp.json())
.then((data) => setresponse(data))
.finally(() => setIsLoading(false));
}, []);
3) And to filter the data just filter the response as:
const handleDelete = (key) => {
setresponse((data) => data.filter((o) => o.id !== key));
};
CodePudding user response:
Try this?
const url = "https://course-api.com/react-tours-project";
function Card() {
const handleDelete = (id) => {
// use id value from api data
setresponse((response) => response.filter((item) => item.id !== id))
}
const[isOpen,setisOpen]=useState(false)
const[response, setresponse]=useState(null)
useEffect(() => {
fetch(url)
.then(resp => resp.json())
.then((data) =>setresponse(data));
console.log(response)
}, [])
return (
<div className="section">{response ?
Object.keys(response).map((item, i) => (
<li className="travelcompany-input" key={i}>
<div className="single-tour">
<img src={response[item].image} alt="" />
<footer>
<div className="tour-info">
<h4>{response[item].name}</h4>
<div className="tour-price">
<h4>${response[item].price}</h4>
</div>
</div>
<div className="delete-btn" onClick={()=>handleDelete(response[item].id)}>Not Interested</div>
</footer>
</div>
</li>
))
:<h2>Loading...</h2>}
</div>
);
}
export default Card;