Why does React tell me unexpected token "." - reactjs

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>
);
}

Related

How to get specific data from api with condition

Hello so i tried to make an website using Goole Books API. I want to get the listPrice from the object, but theres some of the book that doesnt have the listPrice in them. So for the example in object number 1 there is some code called saleability: "NOT_FOR_SALE" meanwhile object number 2 have and saleability: "FOR_SALE". If i tried to map the data, there is a error Uncaught TypeError: i.saleInfo.saleability.listPrice is undefined. How do you make spesific condition for this problem.
This is the code :
const CardBooks = (props) => {
const url = "https://www.googleapis.com/books/v1/volumes?q=:keyes&key=AIzaSyDIwDev4gFHRqCh4SSaO9eLKEeI7oYt6aE&maxResults=27"
const result = "&maxResults=40"
const [bookHome, setBookHome] = useState([]);
const [modalShow, setModalShow] = React.useState(false);
useEffect( () => {
axios
.get(`${url}`)
.then( (res) => {
setBookHome(res?.data?.items)
console.log(res?.data?.items)
})
.catch(console.error);
}, [])
return (
<div>
<Container fluid className='wrapper'>
{bookHome && bookHome.map((i, index) => {
return(
<div className='image-container' key={index}>
<div className="book read">
<div className="cover">
<img src={i.volumeInfo.imageLinks.thumbnail} />
</div>
<div className="info">
<h3 className="title">{i.volumeInfo.title}</h3>
</div>
<Example
thumbnail={i.volumeInfo.imageLinks.thumbnail}
title={i.volumeInfo.title}
description={i.volumeInfo.description}
category={i.volumeInfo.categories}
page={i.volumeInfo.pageCount}
language={i.volumeInfo.language}
publisher={i.volumeInfo.publisher}
published={i.volumeInfo.publishedDate}
link={i.volumeInfo.previewLink}
epub={i.accessInfo.epub.isAvailable}
currency={i.saleInfo.saleability.listPrice.currencyCode}
price={i.saleInfo.saleability.listPrice.amount}
/>
</div>
</div>
)
})}
</Container>
</div>
)
}
export default CardBooks
Basically you just need a null/undefined check, a quick and dirty solution:
currency={i.saleInfo.saleability.listPrice ? i.saleInfo.saleability.listPrice.currencyCode : ''}
It's better to use conditional rendering and/or passing the whole object to the component and handling it inside.

Only one prop is able to pass the data

When I try to pass props from one component to another, only one of them receives data. I am not able to get "users" details to AccountabilityChart component.
I am only able to get data props but not users props. What is the issue? I am not able to figure it out the behaviour. Can any one explain why this happens and if their is a way to have both the props
const Card = (props: any) => {
useEffect(()=>{
console.log("These are props: ", props);
}, []);
const [selectedOption, setSelectedOption] = useState(null);
return (
<ul>
{props.data.map((item: any, index: any) => (
<React.Fragment key={item.name}>
<li>
<div className="card">
<div className="card-body">
<p>{item.name}</p>
</div>
<div>
<Select
defaultValue={selectedOption}
onChange={handleChange}
className="select"
options={props.users}
/>
</div>
<div></div>
</div>
{item.children?.length && <Card data={item.children} users={[]} />}
</li>
</React.Fragment>
))}
</ul>
);
};
const AccountabilityChartComponent = () => {
const [hierarchy, setHierarchy] = useState([]);
const [users, setUsers] = useState([]);
useEffect(() => {
someApiCall.then(
function success(results) {
setHierarchy(results.entities);
}
);
someApiCall.then(
function success(results: any) {
setUsers(wrapped);
}
);
}, []);
return (
<div className="grid">
<div className="org-tree">
<Card
users={users}
data={hierarchy}
/>
</div>
</div>
);
};
export default AccountabilityChartComponent;
Organizational hierarchy I am trying to create
Console log is called 4 times. It means the state is updated 4 times? Will it effect my performance?

Use State not updating as expected

Fairly new to react and trying to build a clone of The Movie Database site. I want this toggle switch to change my api call from movies to tv. It starts working after a couple clicks, but then it throws everything off and it's not displaying the correct items anyway. Not really sure what's going on here...or even why it starts working after two clicks. Anyone know whats up with this?
import React, { useState, useEffect } from "react";
import axios from "axios";
import API_KEY from "../../config";
const Popular = ({ imageUri }) => {
// GET POPULAR MOVIES
const [popularMovies, setPopularMovies] = useState("");
const [genre, setGenre] = useState("movie");
console.log(genre);
const getPopular = async () => {
const response = await axios.get(
`https://api.themoviedb.org/3/discover/${genre}?sort_by=popularity.desc&api_key=${API_KEY}`
);
setPopularMovies(response.data.results);
};
useEffect(() => {
getPopular();
}, []);
const listOptions = document.querySelectorAll(".switch--option");
const background = document.querySelector(".background");
const changeOption = (el) => {
let getGenre = el.target.dataset.genre;
setGenre(getGenre);
getPopular();
listOptions.forEach((option) => {
option.classList.remove("selected");
});
el = el.target.parentElement.parentElement;
let getStartingLeft = Math.floor(
listOptions[0].getBoundingClientRect().left
);
let getLeft = Math.floor(el.getBoundingClientRect().left);
let getWidth = Math.floor(el.getBoundingClientRect().width);
let leftPos = getLeft - getStartingLeft;
background.setAttribute(
"style",
`left: ${leftPos}px; width: ${getWidth}px`
);
el.classList.add("selected");
};
return (
<section className="container movie-list">
<div className="flex">
<div className="movie-list__header">
<h3>What's Popular</h3>
</div>
<div className="switch flex">
<div className="switch--option selected">
<h3>
<a
data-genre="movie"
onClick={(e) => changeOption(e)}
className="switch--anchor"
>
In Theaters
</a>
</h3>
<div className="background"></div>
</div>
<div className="switch--option">
<h3>
<a
data-genre="tv"
onClick={(e) => changeOption(e)}
className="switch--anchor"
>
On TV
</a>
</h3>
</div>
</div>
</div>
<div className="scroller">
<div className="flex flex--justify-center">
<div className="flex flex--nowrap container u-overScroll">
{popularMovies &&
popularMovies.map((movie, idX) => (
<div key={idX} className="card">
<div className="image">
<img src={imageUri + "w500" + movie.poster_path} />
</div>
<p>{movie.title}</p>
</div>
))}
</div>
</div>
</div>
</section>
);
};
export default Popular;
You're using the array index as your key prop when you're mapping your array.
You should use an id that is specific to the data that you're rendering.
React uses the key prop to know which items have changed since the last render.
In your case you should use the movie id in your key prop instead of the array index.
popularMovies.map((movie) => (
<div key={movie.id} className="card">
<div className="image">
<img src={imageUri + 'w500' + movie.poster_path} />
</div>
<p>{movie.title}</p>
</div>
));
Also
You're calling the api directly after setGenre. However state changes aren't immediate. So when you're making your api call you're still sending the last movie genre.
Two ways of fixing this:
You could call your function with the genre directly, and change your function so it handles this case:
getPopular('movie');
Or you could not call the function at all and add genre as a dependency of your useEffect. That way the useEffect will run each time the genre change.
useEffect(() => {
getPopular();
}, [genre]);
PS: You should consider splitting your code into more component and not interacting with the DOM directly.
To give you an idea of what it could look like, I refactored a bit, but more improvements could be made:
const Popular = ({ imageUri }) => {
const [popularMovies, setPopularMovies] = useState('');
const [genre, setGenre] = useState('movie');
const getPopular = async (movieGenre) => {
const response = await axios.get(
`https://api.themoviedb.org/3/discover/${movieGenre}?sort_by=popularity.desc&api_key=${API_KEY}`
);
setPopularMovies(response.data.results);
};
useEffect(() => {
getPopular();
}, [genre]);
const changeHandler = (el) => {
let getGenre = el.target.dataset.genre;
setGenre(getGenre);
};
const isMovieSelected = genre === 'movie';
const isTvSelected = genre === 'tv';
return (
<section className="container movie-list">
<div className="flex">
<MovieHeader>What's Popular</MovieHeader>
<div className="switch flex">
<Toggle onChange={changeHandler} selected={isMovieSelected}>
In Theaters
</Toggle>
<Toggle onChange={changeHandler} selected={isTvSelected}>
On TV
</Toggle>
</div>
</div>
<div className="scroller">
<div className="flex flex--justify-center">
<div className="flex flex--nowrap container u-overScroll">
{popularMovies.map((movie) => {
const { title, id, poster_path } = movie;
return (
<MovieItem
title={title}
imageUri={imageUri}
key={id}
poster_path={poster_path}
/>
);
})}
</div>
</div>
</div>
</section>
);
};
export default Popular;
const Toggle = (props) => {
const { children, onChange, selected } = props;
const className = selected ? 'switch--option selected' : 'switch--option';
return (
<div className={className}>
<h3>
<a
data-genre="movie"
onClick={onChange}
className="switch--anchor"
>
{children}
</a>
</h3>
<div className="background"></div>
</div>
);
};
const MovieHeader = (props) => {
const { children } = props;
return (
<div className="movie-list__header">
<h3>{children}</h3>
</div>
);
};
const MovieItem = (props) => {
const { title, imageUri, poster_path } = props;
return (
<div key={idX} className="card">
<div className="image">
<img src={imageUri + 'w500' + poster_path} />
</div>
<p>{title}</p>
</div>
);
};

Why is my state's value is always undefined?

I've read all the question asked that similar to my problem , but it still cant's solve my issues . I'm fetching datas from an api and assign it's values into my state , the program compiled successfully but this message appears in the browser "TypeError: weatherData.main is undefined"
Here's my code
import './App.css';
import React,{useEffect,useState} from 'react';
function App() {
const [weatherData,setWeatherData] = useState({});
const [position,setPosistion] = useState({});
useEffect(()=>{
navigator.geolocation.getCurrentPosition( pos => {
setPosistion(()=>{
return {
latitude : pos.coords.latitude,
longitude : pos.coords.longitude
}
})
});
},[])
useEffect(()=>{
fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${position.latitude}&lon=${position.longitude}&units=metric&appid=a*****5`)
.then( res => res.json() )
.then( resJson => {
setWeatherData(()=>resJson)
})
},[position]);
return (
<div className="App">
<Weather weatherData={weatherData} />
</div>
);
}
const Weather = ({weatherData}) => {
return(
<React.Fragment>
<div className="location-time">
<span id="location">{weatherData.name}</span>
</div>
<div className="weather">
<span className="temp">{`${weatherData.main.temp} C`}</span>
<div className="icon"></div>
<div className="description">{weatherData.weather[0].main}</div>
<div className="low-max">{`max : ${weatherData.main.temp_max} min : ${weatherData.main.temp_min}`}</div>
<div className="feels-like">{`feels like : ${weatherData.main.feels_like}`}</div>
<button >REFRESH</button>
</div>
</React.Fragment>
)
}
export default App;
the state contains
{"coord":{"lon":106.8451,"lat":-6.2146},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"base":"stations","main":{"temp":302.76,"feels_like":307.06,"temp_min":300.15,"temp_max":305.93,"pressure":1007,"humidity":74},"visibility":6000,"wind":{"speed":2.57,"deg":340},"clouds":{"all":40},"dt":1613038370,"sys":{"type":1,"id":9383,"country":"ID","sunrise":1612997835,"sunset":1613042198},"timezone":25200,"id":1642911,"name":"Jakarta","cod":200}
Before the data is fetched, weather is initialised to be a empty object and hence weather.main is undefined.
You should consider rendering a fallback page till weather data is fetched
const Weather = ({weatherData}) => {
if(Object.keys(weatherData).length === 0) {
return <div>{/* Somee info here or maybe a loader*/}</div>
}
return(
<React.Fragment>
<div className="location-time">
<span id="location">{weatherData.name}</span>
</div>
<div className="weather">
<span className="temp">{`${weatherData.main.temp} C`}</span>
<div className="icon"></div>
<div className="description">{weatherData.weather[0].main}</div>
<div className="low-max">{`max : ${weatherData.main.temp_max} min : ${weatherData.main.temp_min}`}</div>
<div className="feels-like">{`feels like : ${weatherData.main.feels_like}`}</div>
<button >REFRESH</button>
</div>
</React.Fragment>
)
}

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

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!

Resources