React: Parsing error: Unexpected token, expected "(" - reactjs

i am getting Parsing error: Unexpected token, expected "(".
I have no idea where i'm getting this unexpected error. anyways i'm probably new to reactJS. It would be great if anybody could figure out where i'm getting this unexpected error. thank you so much in advance.
./src/components/listing/Search.js :
function PostListPageByUser() {
const [posts, setPost] = useState([]);
const [userId, setUserId] = useState([]);
let signal = axios.CancelToken.source();
function handleChange(event) {
setUserId(event.target.value);
}
function handleClick = (event) => {
axios.get("http://localhost:8000/api/car/p_list?search=" + event, {
cancelToken: signal.token,
})
.then(res => {
const posts = res.data;
setPost(posts);
}).catch(err => {
console.log(err);
});
}
return (
<React.Fragment>
<section class="product_list section_padding">
<div class="container">
<div class="row">
<div class="col-md-3">
<div class="product_sidebar">
<div class="single_sedebar">
<form>
<input type="text" name="search" onChange={handleChange} placeholder="Search keyword"/>
<i class="ti-search" onClick={handleClick}></i>
</form>
</div>
</div>
</div>
<div class="col-sm-9">
<div class="product_list">
<div class="row"> <br/><br/><br/>
{
posts.map((post) => {<ul key={post.id}>
<div class="col-lg-8 col-xl-9">
<img src={post.product_image} alt="" class="img-fluid" />
<h3>{post.title}</h3>
</div>
</ul>})
}
</div>
</div>
</div>
</div>
</div>
</section>
</React.Fragment>
);
}

I see 2 issues with your snippet.
Firstly, since you are using an arrow function for handleClick, you need to change it to:
const handleClick = (event) => {
axios.get("http://localhost:8000/api/car/p_list?search=" + event, {
cancelToken: signal.token,
})
.then(res => {
const posts = res.data;
setPost(posts);
}).catch(err => {
console.log(err);
});
Secondly,
{
posts.map((post) => {
return(
<ul key={post.id}>
<div class="col-lg-8 col-xl-9">
<img src={post.product_image} alt="" class="img-fluid" />
<h3>{post.title}</h3>
</div>
</ul>
)
})
}
As an aside, the ul tag is misused here. You should use a div instead. That should not stop your code from working though but for the sake of knowledge and working in a production environment, it's important you always use the right tags. You can learn more here

you need to change this part
const handleClick = (event) => {
axios.get("http://localhost:8000/api/car/p_list?search=" + event, {
cancelToken: signal.token,
})
.then(res => {
const posts = res.data;
setPost(posts);
}).catch(err => {
console.log(err);
});
}
you cannot use the function and arrow function syntax simultaneously!

Related

I am getting a response saying api token is undefined in React

I have written correctly in .env.local file as REACT_APP_API_KEY=myapikeytoken and my key is also correct but I am getting token undefined when I console.log response. This is the website url - https://app.json-generator.com/ from where I generated a fake API.
Below is the code where I am fetching an api.
import React, { useEffect } from "react";
import "./header.css";
const Header = () => {
const getHeaderData = async () => {
const apiKey = process.env.REACT_APP_API_KEY;
const response = await fetch(
`https://api.json-generator.com/templates/jy5YJ7qSuzOt/data?access_token=${apiKey}`
);
console.log(response);
if (response.ok) {
console.log(response);
} else {
console.log("response failed");
}
const data = response.json();
console.log(data);
};
useEffect(() => {
getHeaderData();
}, []);
return (
<>
<div className="dvHeader">
<div className="container-lg">
<div className="row align-items-center pt-1">
<div className="col d-lg-none">
<i className="fa-solid fa-bars"></i>
</div>
<div className="col col-lg-auto text-center text-lg-left">
<img
width={50}
src="https://static.wixstatic.com/media/2c0034_a27b95faba1d432fbddcf6ac4e9683ba~mv2.png"
alt=""
/>
</div>
<div className="dvSlideMenu col-lg-auto px-0 px-lg-3">
<button className="btn btn-black closeBtn d-lg-none">
<i className="fa-solid fa-xmark"></i>
</button>
<ul className="dvMenu">
<li>
Home
</li>
<li>
Shop
</li>
<li>
Login
</li>
<li>
Signup
</li>
</ul>
</div>
<div className="col col-lg-auto ml-lg-auto text-right">
<i className="fa-solid fa-cart-shopping"></i>
</div>
</div>
</div>
</div>
</>
);
};
export default Header;
Fetch is already async and you do not need to await it. I would also suggest that you use fetch like this:
const getHeaderData = async () => {
fetch(`https://api.json-generator.com/templates/jy5YJ7qSuzOt/data?access_token=${process.env.REACT_APP_API_KEY}`)
.then((response) => response.json())
.then((response) => {
// Response is ok, do something
})
.catch((error) => {
// Some error, handle it here
});
}
Read more about it:
https://reactjs.org/docs/faq-ajax.html
https://www.freecodecamp.org/news/fetch-data-react/
I found the issue. The issue was await. I didn't wrote await before response.json().
Code should look like this below:
const getHeaderData = async () => {
const apiKey = process.env.REACT_APP_API_KEY;
const response = await fetch(
`https://api.json-generator.com/templates/jy5YJ7qSuzOt/data?access_token=${apiKey}`
);
console.log(response);
if (response.ok) {
console.log(response);
} else {
console.log("response failed");
}
const data = await response.json(); //added await here
console.log(data);
};

filter component react either with search or buttons

I have a page that renders a list of dogs from the DogAPI. I don't want to make too many changes in existing code but would like to filter what is currently displayed, was thinking either search box or buttons that show the different breeds. What would be the best approach to do this? I have looked at this article (https://dev.to/salehmubashar/search-bar-in-react-js-545l) but with what I currently have it might cause some things to break, especially the part where I use the ID to link to individual pages.
Here is what I have currently:
import { useState, useEffect } from "react";
import {
Link
} from 'react-router-dom';
import Loading from "./Loading";
export default function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(`https://api.thedogapi.com/v1/breeds`, {
method: "GET", // default GET
headers: {
'Content-Type': 'application/json',
'x-api-key': `${process.env.REACT_APP_API_KEY}`,
},
})
.then((response) => {
if (!response.ok) {
throw new Error(
`This is an HTTP error: The status is ${response.status}`
);
}
return response.json();
})
.then((actualData) => {
setData(actualData);
setError(null);
console.log("data", actualData);
})
.catch((err) => {
setError(err.message);
setData(null);
})
.finally(() => {
setLoading(false);
});
}, []);
return <div className="container-fluid">
{loading && <div className="text-center"><Loading /></div>}
{error && (
<div>{`There is a problem fetching the post data - ${error}`}</div>
)}
<ul className="row justify-content-center">
{data &&
data.map(({id,name,image,bred_for,life_span}) => (
<Link to={"/dog/" + id} className="col-md-4 col-sm-6 card my-3 py-3 border-0">
<li key={id}>
<h3>{name}</h3>
<div className="card-img-top text-center">
<img src={image.url} className="photo w-75" />
</div>
<p>{bred_for}</p>
<p>{life_span}</p>
</li>
</Link>
))}
</ul>
</div>;
}
I simplified things down a bit for the sake of example, but this is a little search filter to use as an example to get started. Could hook up the same logic to buttons or preconfigured filter options instead of search input.
import { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState([]);
const [filtered, setFiltered] = useState([]);
useEffect(() => {
fetch(`https://api.thedogapi.com/v1/breeds`, {
method: "GET", // default GET
headers: {
"Content-Type": "application/json",
"x-api-key": `${process.env.REACT_APP_API_KEY}`
}
})
.then((response) => {
if (!response.ok) {
throw new Error(
`This is an HTTP error: The status is ${response.status}`
);
}
return response.json();
})
.then((actualData) => {
setData(actualData);
setFiltered(actualData);
});
}, []);
return (
<div className="container-fluid">
<div>
<input
onChange={(event) => {
const value = event.target.value;
const filtered = data.filter((dog) => dog.name.includes(value));
setFiltered(filtered);
}}
/>
</div>
<ul className="row justify-content-center">
{filtered.map(({ id, name, image, bred_for, life_span }) => (
<a
to={"/dog/" + id}
className="col-md-4 col-sm-6 card my-3 py-3 border-0"
key={name}
>
<li key={id}>
<h3>{name}</h3>
<div className="card-img-top text-center">
<img src={image.url} className="photo w-75" height="48px" />
</div>
<p>{bred_for}</p>
<p>{life_span}</p>
</li>
</a>
))}
</ul>
</div>
);
}

Why is my fetched data not appearing in my React hooks component?

I am trying to load data into my component for it to be displayed. I thought the issue was that I wasn't using async/await for the fetch, but even after adding that it still is not loading. I am logging out the "offerings" and it is just showing the empty array. How do I keep the component from rendering until after the data is loaded??
Thanks in advance!
const [offerings, setOfferings] = useState([]);
const loadData = async () => {
const res = await fetch(`http://52.207.83.69` + `${CRUD_OFFERING}`);
setOfferings(await res.json());
console.log(offerings, 'offerings')
};
useEffect(async () => {
navbarToggle();
await loadData();
}, []);
const dispatch = useDispatch();
const modalState = useSelector((state) => state.modal);
const modalToggle = () => {
dispatch({
type: MODAL_TOGGLE,
payload: !modalState.show,
});
ga.event("navbar_requestdemo_clicked");
};
const navbarOpenState = useSelector((state) => state.navbar);
const navbarToggle = () => {
if (!navbarOpenState.open) return;
dispatch({
type: NAVBAR_OPEN,
payload: false,
});
};
return (
<div
className="d-flex justify-content-center align-items-center bg-color-white fc-px-15"
onClick={navbarToggle}
>
<div className={homeStyles["padded-body"] + " col-11 p-0"}>
<div className=" position-relative bg-color-white">
<div className={homeStyles["img-holder"]}></div>
<div className="col-12 column position-absolute top-0 d-flex justify-content-center">
<div className="col-lg-6 col-12 fc-mt-2">
<SearchBar />
</div>
</div>
<div className="position-absolute top-50 translateY-middle">
<div className="position-relative">
<h1 className={`${homeStyles["hero-text"]} font-weight-bolder`}>
Building
<br />
Meaningful
<br />
Engagement
</h1>
<button
className="btn btn-primary-round mt-3 px-3 py-2"
onClick={() => {
modalToggle();
}}
>
Request access
</button>
</div>
</div>
</div>
<div
id={homeStyles["discover-section"]}
className="d-flex justify-content-center align-items-center"
>
<div className="col-12 column">
<h4 className="font-weight-bold">Discover</h4>
<div
id={homeStyles["offer-section"]}
className="row justify-content-center align-items-center"
>
{!offerings?.length &&
<h4 className="text-center">There are no active offerings.</h4>
}
</div>
<OfferingCarousal
offeringsList={offerings}
name={"Offerings"}
/>
<div id={homeStyles["consultancy-section"]} className="">
<div className="row">
<div
className="d-flex justify-content-center align-items-center col-lg-6 col-12 px-0 mt-3 mb-4"
id={homeStyles["consultancy-div"]}
>
<div className="col-12 column p-5">
<h1 className="font-weight-bold">Add your consultancy</h1>
<h5 className="mt-4">
Reach more people and organizations
</h5>
<Link href="/consultancies">
<button className="btn btn-primary-round mt-4">
Learn more
</button>
</Link>
</div>
</div>
<div className="col-lg-6 col-12 px-0">
<img
src="/images/Rachael_glasses_home_page.jpg"
id={homeStyles["consultant-img"]}
className="mt-3"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default HomeNew;
You can check if the data is present before you consume the data.
const [offerings, setOfferings] = useState([]);
const loadData = async () => {
const res = await fetch(`http://52.207.83.69` + `${CRUD_OFFERING}`);
setOfferings(res.json());
console.log(res, 'offerings')
};
useEffect(() => {
navbarToggle();
loadData(); // await has no affect inside useEffect for top level functions
}, []);
// removed internal code for clarity
const dispatch = useDispatch(...yourCode);
const modalState = useSelector(...yourCode);
const modalToggle = () => {...yourCode};
const navbarOpenState = useSelector(...yourCode);
const navbarToggle = () => {...yourCode};
// check after the hooks and before the consuming the data
if(!offerings && !offerings.length) return <>No offerings</>;
return <div>your side nav</div>;
};
It's also good practice to catch asynchronous errors as they occur to prevent your a single component form breaking your whole app. You can also take advantage of the try...catch and put in loading and error states too.
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [offerings, setOfferings] = useState([]);
const loadData = async () => {
try {
setError(false);
setLoading(true);
const res = await fetch(`http://52.207.83.69` + `${CRUD_OFFERING}`);
setOfferings(res.json());
} catch (e){
setError(true)
} finally {
setLoading(false);
}
};
// other code from above
if(error) return <>error</>;
if(loading) return <>loading</>;
if(!offerings && !offerings.length) return <>No offerings</>;
return <div>your side nav</div>;
};
async function can't be put in the useEffect hook directly.
https://prnt.sc/1lu7vdc
It can be like this.
useEffect(() => {
...
(async ()=>{
await loadData()
})();
}, []);
But in your case, I think you don't need to wait until loadData function is executed.
Just make sure you handle exceptions on the rendering for Empty data.

Why does React tell me unexpected token "."

I'm trying to display an json array on the screen but react tells me unexpected token "." I have searched around for 3 hours now but I can't figure out what is wrong or how to fix this. The other parts of the detail object all display correctly but for some reason the array just doesn't want to. I hope someone can help me with this problem.
the exact error I get is:
and the json in console log.
below is my code for the component.
function GeneDetail({ match }) {
useEffect(() => {
fetchDetails();
}, []);
const [detail, setDetail] = useState({})
//const [alleles, setAlleles] = useState([])
const fetchDetails = async () => {
const fetchDetails = await fetch(
'/api/get_genedetail?g='+match.params.genename+''
);
const detail = await fetchDetails.json()
setDetail(detail)
//setAlleles(detail.alleles)
}
console.log('alleles', detail.alleles)
return(
<div className="main-content">
<Container maxWidth="lg">
<div className="grid-container">
<div className="grid-title">
<h2>Gene: <i>{detail.geneName}</i></h2>
</div>
<div className="grid-subtitle">
<h3>Type: {detail.segmentFullName}</h3>
</div>
<div className="grid-alleles">
test
{detail.alleles ?
{detail.alleles.map(function (allele, i) {
return <div key={i}>
<h5>{allele.Number}</h5>
</div>
})}
: (<p>"No alleles found."</p>)}
</div>
</div>
</Container>
</div>
);
}
React errors can be confusing, the problem here is not that you have a dot there. Instead, you declare a variable expression in a variable expression, essentially like this:
{condition?{mappedData}:(alternative)}
You cannot declare an expression in an expression, you should've written it like this:
{detail.alleles ?
detail.alleles.map(function (allele, i) {
return <div key={i}>
<h5>{allele.Number}</h5>
</div>
})
: (<p>No alleles found.</p>)}
UpVote, if the solution works
function GeneDetail({ match }) {
useEffect(() => {
fetchDetails();
}, []);
const [detail, setDetail] = useState({})
//const [alleles, setAlleles] = useState([])
const fetchDetails = async () => {
const fetchDetails = await fetch(
'/api/get_genedetail?g='+match.params.genename+''
);
const detail = await fetchDetails.json()
setAlleles(detail.alleles)
}
console.log('alleles', detail.alleles)
return(
<div className="main-content">
<Container maxWidth="lg">
<div className="grid-container">
<div className="grid-title">
<h2>Gene: <i>{detail.geneName}</i></h2>
</div>
<div className="grid-subtitle">
<h3>Type: {detail.segmentFullName}</h3>
</div>
<div className="grid-alleles">
test
{alleles.length >= 0 ?
{alleles.map( (allele, i) => {
return <div key={i}>
<h5>{allele.Number}</h5>
</div>
})}
: (<p>"No alleles found."</p>)}
</div>
</div>
</Container>
</div>
);
}

React useState not triggering re-render of child component

I cant seem to figure out why my MovieDetailCard component will not re-render when the movie state changes. I am passing in the movie object. When I update the state the log outputs correctly in the useEffect but the MovieDetailsCard never receives the updated object.
const MovieDetails = () => {
const [movie, setMovie] = useState({});
const { id } = useParams();
const { poster } = useParams();
useEffect(() => {
const fetchMovie = async () => {
const response = await fetch(
`http://www.randyconnolly.com/funwebdev/3rd/api/movie/movies.php?id=${id}`
);
const data = await response.json();
setMovie({ ...data });
};
fetchMovie();
}, []);
useEffect(() => {
console.log(movie); // this successfully outputs when movie updates
}, [movie]);
return (
<div className="row">
<div className="col s12 m6">
<MovieDetailsCard poster={poster} movie={movie} /> // this does not update
</div>
<div className="col s12 m6">
<CastCrewCard />
</div>
</div>
);
};
Below is the MovieDeatailsCard. In the useEffect the console.log(movie) always returns null.
const MovieDetailsCard = ({ poster, movie }) => {
useEffect(() => {
console.log("in details");
console.log(movie);
}, []);
return (
<div className="card">
<div className="card-content">
<div className="row">
<div className="col s6">
<span className="card-title">Movie Title</span>
</div>
<div className="col s6 favouriteButton">
<FavouriteButton className="waves-effect waves-light btn">
<i className="material-icons">favorite</i>
</FavouriteButton>
</div>
</div>
<div className="row">
<div className="col s12 m6">
<img src={`https://image.tmdb.org/t/p/w342/${poster}.jpg`} alt="" />
</div>
<div className="col s12 m6">
<p>{movie.title}</p>
</div>
</div>
</div>
</div>
);
};
export default MovieDetailsCard;
Thanks guys for the input. This seems to be resolved now. before I was setting data by setData(data) but when I changed to setData({...data}) that worked!
By default, effects run after every completed render, but you can choose to fire them only when certain values have changed.
refer: https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect
If you want to run an effect and clean it up only once (on mount and
unmount), you can pass an empty array ([]) as a second argument. This
tells React that your effect doesn’t depend on any values from props
or state, so it never needs to re-run. This isn’t handled as a special
case — it follows directly from how the dependencies array always
works.
try updating useEffect dependendecy to include [id]:
useEffect(() => {
const fetchMovie = async () => {
const response = await fetch(
`http://www.randyconnolly.com/funwebdev/3rd/api/movie/movies.php?id=${id}`
);
const data = await response.json();
setMovie({ ...data });
};
fetchMovie();
}, [id]);
Are you sure that you are going receive data from API? The website does not shows up.
Try this to test the API
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json)
In the state declaration (useState) it is better to declare all the keys that you are going to receive all from the API

Resources