okay guys so new update. so i did jus that . i moved all the elements to the rendering and tried to just get the state to be alone. when i tried that it told me that map wasnt able to read properties of undefined. so what i did was added the object keys . the page rendered ... kinda. it rendered without all the data. i attached the updated code in here but now im kinda confused because its not showing an error this time .its just not displaying the info. can someone tell me what im doing wrong here ?
CodePudding user response:
The error message tells you that user.toLowerCase
is not a function, indicating that user
is not a string as toLowerCase
only works with strings. Instead, user
is the ul
element you create in the setInfo(json.students.map())
call in the useEffect
. It's not ideal to store DOM elements in state for this reason as it's not easy to work with. Instead, leave your info
state variable as an array of objects, and move the logic for creating DOM elements in your return
.
In addition, I would not change your state when you filter as you would not be able to easily get the original, unfiltered state values back. Keep track of your filters in state and do conditional rendering based on the filters in your return.
CodePudding user response:
You setting your user info as a ul html list. Instead set the userInfo the json response and then map the ul list when you render the component.
I'm not sure what your user json looks like, so you might have to play around with that.
import React, { useEffect, useState } from "react";
import Card from "@material-ui/core/Card";
import CardContent from '@material-ui/core/CardContent';
import Grid from "@material-ui/core/Grid";
import { Input } from "@material-ui/core";
function StudentProfiles() {
const [info, setInfo] = useState();
const [search, setSearch] = useState('');
useEffect(() => {
fetch("https://api.hatchways.io/assessment/students")
.then(response => response.json())
.then(json => setInfo(json))
},[]);
const average = (array) => array.reduce((a,b) => a b )/ array.length;
const filter = (e) => {
const keyword = e.target.value;
if(keyword !== '') {
const results = info.filter((user) => {
return user.students.toLowerCase().startsWith(keyword.toLowerCase());
});
setInfo(results);
} else {
setInfo(info)
}
}
return (
<div>
<Card className="card">
<CardContent className="scrollbar scrollbar-primary mt-5 mx-auto">
<Input
className="searchBar"
icon="search"
placeholder="Search by name"
onChange={filter}
/>
{ user.students.map((name) => (
<ul className = "border" key={name.id}>
<Grid item xs={3} sm={6} md={12} style={{display: "flex", gap:"3.5rem", paddingBottom:"8px"}}>
<img alt ="" src={name.pic} className="picture"></img>
<Grid container style={{display: "inline"}} align="left" justify="flex-end" alignItems="flex-start">
<Grid className="studentNames">
<span>{name.firstName " " name.lastName}</span>
</Grid>
<span>{name.email}</span>
<br/>
<span>{name.company}</span>
<br/>
<span>{name.skill}</span>
<br/>
<span>Average: {average(name.grades).toFixed(3)}%</span>
</Grid>
</Grid>
</ul>
)))}
</CardContent>
</Card>
</div>
)
}
export default StudentProfiles;