Access Object Properties in React - html

In my react app, I have an array of objects in a file(users.js) and I have another file(contacts.jsx). I am putting the material ui card in contacts.jsx file and in that card I want to access properties of object.
I have tried to access it by using dot(.) operator but I am getting undefined in console.log. What mistake am I doing and How can I access properties like avatar, email, first_name etc.?
users.js
const users = [{
id: 1,
email: "george.bluth#reqres.in",
first_name: "George",
last_name: "Bluth",
avatar: "https://reqres.in/img/faces/1-image.jpg"
},
{
id: 2,
email: "janet.weaver#reqres.in",
first_name: "Janet",
last_name: "Weaver",
avatar: "https://reqres.in/img/faces/2-image.jpg"
}]
export default users;
contacts.jsx
import React from "react";
import FilterListIcon from '#mui/icons-material/FilterList';
import { Button, Card, CardActions, CardContent, CardMedia, Typography } from "#mui/material";
import users from "../constants/users";
const Contacts = () => {
return (
<div className="parentDiv">
{
console.log(users.email,'email') // Result: undefined 'email'
}
<div className="header">
<h1>Robo Space</h1>
<input className="searchFilter" type='text' placeholder="Search here" />
<span className="filterIcon"><FilterListIcon /></span>
</div>
<div className="body">
<Card sx={{ maxWidth: 345 }}>
<CardMedia
component="img"
height="140"
img={users.avatar}
alt="robo img"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{users.first_name}
</Typography>
<Typography variant="body2" color="text.secondary">
{users.last_name}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Show More</Button>
</CardActions>
</Card>
</div>
</div>
)
}
export default Contacts;

To access single properties you can use the dot operator like users[0].email, to access the properties dynamically you can use .map() like that:
import React from "react";
import FilterListIcon from '#mui/icons-material/FilterList';
import { Button, Card, CardActions, CardContent, CardMedia, Typography } from "#mui/material";
import users from "./users";
const Contacts = () => {
return (
<div className="parentDiv">
{
console.log(users[0].email,'email') // Result: undefined 'email'
}
<div className="header">
<h1>Robo Space</h1>
<input className="searchFilter" type='text' placeholder="Search here" />
<span className="filterIcon"><FilterListIcon /></span>
</div>
<div className="body">
{users.map((user)=>{
return (
<Card sx={{ maxWidth: 345 }}>
<CardMedia
component="img"
height="140"
src={user.avatar}
alt="robo img"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{user.first_name}
</Typography>
<Typography variant="body2" color="text.secondary">
{user.last_name}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Show More</Button>
</CardActions>
</Card>
)
})}
</div>
</div>
)
}
export default Contacts;
Here is a Sandbox in case you need it.

Related

How to Implement a search function in reactJS using MaterialUI

I try to develop a pokedex using the pokeapi. For now it works fine, the pokemon are fetched correctly and are displayed in a container. Now i want to implement a function to search and filter the pokemon. Therefore i used MaterialUI to put a searchBar on top of the App.
The fetched pokemon are given from App.js to my Component PokemonList which maps the data. My idea is now to filter the pokemonData before it is given to PokemonList to map only the pokemon i am looking for. But here i am stuck. I have no idea how to connect the search function with my pokemonData Hook from App.js . Can you help me?
This is my searchBar Component:
const SearchAppBar = () => {
const [search, setSearch] = useState("");
console.log(search)
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static" sx={{ bgcolor: "black"}}>
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="open drawer"
sx={{ mr: 2 }}
>
<MenuIcon />
</IconButton>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' } }}
>
<img src={logo} alt="logo" width="150" height="auto" />
</Typography>
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
onChange={(e) => setSearch(e.target.value)}
id = 'searchbox'
placeholder="Search for Pokémon..."
inputProps={{'aria-label': 'search'}}
/>
</Search>
</Toolbar>
</AppBar>
</Box>
);
}
export default SearchAppBar;
you should save the entered value from input into a state and filter your data based on that state

How to get Formik error messages to align with input box?

How do I get these messages to align with the input boxes? I'm not sure how I could style this?
The Formik exists outside of the ReactJS return so I can't put it in a and style. And what is the reason that the error message is aligning to the edge of the box anyways? I'm new to React and Formik is what was recommended in the Chakra UI Docs to use for form handling.
Here is my code:
import React from 'react';
import { Text, Box } from '#chakra-ui/react'
import { Input } from "#chakra-ui/input"
import { Button } from "#chakra-ui/button";
import { FormControl, FormLabel, FormErrorMessage } from "#chakra-ui/form-control";
import { Heading, VStack } from "#chakra-ui/layout";
import { useFormik } from "formik";
import * as Yup from "yup";
import "../Signup.css";
import SignupLogo from '../assets/Shots.jpg';
const Signup = () => {
// Formik Hook to validate password and username length
const formik = useFormik({
initialValues: {
username: "",
email: "",
password: ""
},
validationSchema: Yup.object({
username: Yup.string().required("Username Required").min(6, "Username much be minimum of 6 characters long, username too short! "),
password: Yup.string().required("Password Required").min(8, "Password much be minimum of 5 characters long, password too short! "),
}),
onSubmit: (values, actions) => {
alert(JSON.stringify(values, null, 3));
actions.resetForm();
}
});
return (
<body className='SignupImg'>
<VStack
as="form"
mx="auto"
w={{ base: "75%", md: 500 }}
h="100vh"
justifyContent="center"
onSubmit={formik.handleSubmit}
className='winterCitrus'>
<Heading color="#421413">
Sign Up!
</Heading>
{/* Form for Username */}
<FormControl py={3} id="user_id" isInvalid={formik.errors.username && formik.touched.username}>
<FormLabel colorScheme="black">
<Text color="#932D30" textAlign="center">
Username
</Text>
</FormLabel>
<Input
bg="white"
textColor="black"
name='username'
placeholder="enter username"
{...formik.getFieldProps("username")}
width={"300px"}
/>
<FormErrorMessage>{formik.errors.username}</FormErrorMessage>
</FormControl>
{/* Form for Email */}
<FormControl py={3} id="email_id">
<FormLabel>
<Text color="#932D30" textAlign="center">
Email
</Text>
</FormLabel>
<Input
bg="white"
textColor="black"
name='email'
placeholder='enter email'
onChange={formik.handleChange}
value={formik.values.email}
width={"300px"}
/>
</FormControl>
{/* Form for Password */}
<FormControl py={3} id="password_id" isInvalid={formik.errors.password && formik.touched.password}>
<FormLabel>
<Text color="#932D30" textAlign="center">
Password
</Text>
</FormLabel>
<Input
bg="white"
textColor="black"
name='password'
placeholder='enter password'
{...formik.getFieldProps("password")}
width={"300px"}
/>
<FormErrorMessage>{formik.errors.password}</FormErrorMessage>
</FormControl>
<Button type='submit' variant="outline" bgColor="#421413">
Create Account
</Button>
</VStack>
</body>
)
};
export default Signup;
You could try to use something like this in your code for example
{formik.touched.username && formik.errors.username && (
<span className='error'>{formik.errors.username}</span>
)}
You could try MUI. they have dedicated docs for formik and yup

How can i create a dynamic page using parameter in react + Json

How can i create a dynamic page using parameter in react + Json
in my code below i was able to map the json data and i need to create a dynamic url that create the /download page with the json details of the artist when i click on "GET MP3" button.
example: When i click GET MP3 a new tab will open with a url like this https:// mysite.com/
then on the download page i can get all the details from the {data.id}.
Please any idea on how to go around it?
import React, { Component } from "react";
import {
Route,
NavLink,
HashRouter
} from "react-router-dom";
import "../customcss/style.css";
import data from "../artist/toptrending5.json";
const newdata = data.map((item) => {
const searchDownloadData = `download?id=${item.id}&artist=${item.artist}&title=${item.title}&genre=${item.genre}&urldownload=${item.urldownload}`
return (
<>
<div id="playerbackground" key= {data.id} style={{marginTop: '10px'}}>
<div className="row" align="center">
<div className="col">
<img id="Playericon" src={ Playericon } />
</div>
<div className="col ">
<button id="music-play" type="button" className="btn btn-outline-warning"><b>Play</b></button>
</div>
<div className="col-5 " align="center">
<h6 id="music-title"><b> { data.artist} - { data.title }</b></h6>
</div>
<div className="col player-col-sm-2" align="center">
<Link to={searchDownloadData} rel=" noopener noreferrer" id="music-download" className="btn btn-outline-primary"><b> MP3 </b></Link>
</div>
</div>
</div>
</>
)
}
)
export default class Top5 extends Component {
render() {
return (
<>
<h2 id="trendtop5" className="trendtop5">Top 10 Trending Bongo Music</h2>
<div id="" className="container"> {newdata} </div>
<div className="container" style={{marginTop: '10px', paddingRight: '10px' }} >
<button className="btn btn-outline-primary" ><NavLink exact to="/artist">Explore More</NavLink></button>
</div>
<br />
</>
);
}
}
Below is my router
<BrowserRouter>
<div id="wrapper">
<header id="header">
<div className="container">
<div id="logo" className="pull-left">
<img id="logo" src={ logo } />
<h1 id="h1home"><strong> Music</strong></h1>
</div>
<nav id="menu-button-nav">
<ul id="nav" className="nav-menu">
<li className="btn btn-warning"><NavLink exact to="/">Home</NavLink></li>
<li className="btn btn-warning"><NavLink to="/justin">Just In</NavLink></li>
<li className="btn btn-warning"><NavLink to="/artist">Artists</NavLink></li>
<li className="btn btn-warning"><NavLink to="/about">About</NavLink></li>
</ul>
</nav>
</div>
</header>
</div>
<div id="content" className="container" >
<Route exact path="/" component={Home}/>
<Route path="/justin" component={Justin}/>
<Route path="/artist" component={Artists}/>
<Route path="/about" component={About}/>
<Route path="/download" component={DownloadArtist}></Route></Route>
</div>
</BrowserRouter>
Below is my Json data that hold the artist details
[
{
"id":1,
"artist": "Artist 1" ,
"title": "tata",
"genre": "rock",
"urldownload" : "https://drive.google.com/uc?export=download&id=1-"
},
{
"id":2,
"artist": "Artist 1" ,
"title": "tata",
"genre": "rock",
"urldownload" : "https://drive.google.com/uc?export=download&id=1-"
},
{
"id":3,
"artist": "Artist 1" ,
"title": "tata",
"genre": "rock",
"urldownload" : "https://drive.google.com/uc?export=download&id=1-"
},
{
"id":4,
"artist": "Artist 1" ,
"title": "tata",
"genre": "rock",
"urldownload" : "https://drive.google.com/uc?export=download&id=1-"
}
]
Download Page
class DownloadArtist extends Component {
render() {
const url = new URL(window.location.href);
const id = JSON.parse(url.searchParams.get("id"));
const artist = url.searchParams.get("artist");
const title = url.searchParams.get("title");
const genre = url.searchParams.get("genre");
const urldownload = url.searchParams.get("urldownload");
console.log(url)
return (
<>
<section>
<h1 id="artistComingSoon" className="center"> ADVERT!!!</h1>
</section>
<section>
<div className="container">
<p> <strong>User ID: </strong>{id} </p>
<p> <strong>Artist Name: </strong>{artist}</p>
<p> <strong>Title: </strong>{title} </p>
<p> <strong>Genre: </strong>{genre}</p>
<p> <strong>Download Link: </strong>{urldownload}</p>
</div>
</section>
<section>
<h1 id="artistComingSoon" className="center"> ADVERT!!!</h1>
</section>
</>
);
}
}
export default DownloadArtist;
Updated
Solved
To handling URL routes in react, we are already use React Router
React Router allow us to manage routes and handling url with dynamic behavior, so that, what we need to do is:
Build route
Build url which its follow this route
For Example:
<Route path={`download/:type`}>
<myComponent />
</Route>
================
<li>
<Link to=`/download/mp3`>Download MP3</Link>
</li><li>
<Link to=`/download/video`>Download Video</Link>
</li>
If you do this, you will send url params and you can fetch it easy by this:
const {type} = useParams();
Your React app, wich is calling the download page, can pass parameter with the url. Your download page then can read those.
You can specify parameter with an "?" in your url. If you want to, you can send multiple parameter as well.
const url = `https://example.com/download/?id=${data.id}`
In your download page you can read those parameter with the URL class.
const url = new URL(window.location.href);
const id = JSON.parse(url.searchParams.get("id"));
With your example it would be something like this.
import React, { Component } from "react";
import {
Route,
NavLink,
HashRouter
} from "react-router-dom";
import "../customcss/style.css";
import data from "../artist/toptrending5.json";
const newdata = data.map((item) => {
const url = `/download/?id=${item.id}`;
return (
<>
<div id="playerbackground" key={item.id} style={{ marginTop: '10px' }}>
<div className="row" align="center">
<div className="col">
<img id="Playericon" src={Playericon} />
</div>
<div className="col ">
<button id="music-play" type="button" className="btn btn-outline-warning"><b>Play</b></button>
</div>
<div className="col-5 " align="center">
<h6 id="music-title"><b> {item.artist} - {item.title}</b></h6>
</div>
<div className="col player-col-sm-2" align="center">
<Link to={url} rel=" noopener noreferrer" id="music-download" className="btn btn-outline-primary"><b> MP3 </b></Link>
</div>
</div>
</div>
</>
)
}
)
export default class Top5 extends Component {
render() {
return (
<>
<h2 id="trendtop5" className="trendtop5">Top 10 Trending Bongo Music</h2>
<div id="" className="container"> {newdata} </div>
<div className="container" style={{ marginTop: '10px', paddingRight: '10px' }} >
<button className="btn btn-outline-primary" ><NavLink exact to="/artist">Explore More</NavLink></button>
</div>
<br />
</>
);
}
}

How to display data in react?

I have this database schema which I can get from the api when it's successful.
surveys: array of survey objects containing:
(section_id, Course_code, Course_name, Department_id)
I want to display course_code and course_name only.
here is my code:
export default function Dashboard() {
const resp=await Axios({
method:"Get",
url:'http://localhost:5000/api/student/courses',
headers:{"Content-Type":"application/json",
},
data:user,
});
const classes = useStyles();
return (
<GridContainer>
<GridItem xs={12} sm={6} md={3}>
<Card>
<CardHeader color="warning" stats icon>
<CardIcon color="warning">
<Icon>content_copy</Icon>
</CardIcon>
<p className={classes.cardCategory}>Available surveys</p>
<h3 className={classes.cardTitle}>{resp.data.survey_count}</h3>
</CardHeader>
</Card>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<Card>
<CardHeader color="primary">
<h4 className={classes.cardTitleWhite}>Available Surveys</h4>
<p className={classes.cardCategoryWhite}>
Here is the remaining courses surveys to submit
</p>
</CardHeader>
<CardBody>
<Table
tableHeaderColor="primary"
tableHead={["Course Code", "Course Name", "Survey Link"]}
tableData={[
[
//i want to map data here
],
]}
/>
</CardBody>
</Card>
</GridItem>
</GridContainer>
);
}

onClick not propagated

I'm having troubles with creating a simple gallery allowing to print pictures. I constructed the interface. When I click on the print button, I'm not able to propagate event to a function. Funny enough, it always works for just a couple of items in the gallery so that console logs foo. Could you please point me where is the problem? I am using material-ui, tileData is a json with image url etc...
Many thanks!
class Galery extends React.Component {
state = {
tileData: tileData
};
printThis = tile => {
console.log("printing tile... " + tile.target.value);
};
render() {
const classes = this.props;
return (
<div className={classes.root}>
<ButtonAppBar />
<div style={{ marginBottom: 20 }} />
<Grid container spacing={8}>
<Grid item xs={10}>
<GridList
cellHeight={250}
cellWidth={250}
cols={5}
spacing={4}
className={classes.gridList}
>
{tileData.map(tile => (
<GridListTile key={tile.img}>
<img src={tile.img} alt={tile.title} />
<GridListTileBar
title={tile.title}
subtitle={<span>by: {tile.author}</span>}
actionIcon={
<IconButton
className={classes.icon}
value="foo"
onClick={this.printThis}
>
<i className="material-icons md-24 md-light">print</i>
</IconButton>
}
secondActionIcon={
<IconButton className={classes.icon}>
<i className="material-icons md-24 md-light">delete</i>
</IconButton>
}
/>
</GridListTile>
))}
</GridList>
</Grid>
<Grid item xs={2}>
<div className={classes.stats}>
<StatsTable />
</div>
</Grid>
</Grid>
</div>
);
}
}
It works for me to access the object id through event.currentTarget as per github answer here https://github.com/mui-org/material-ui/issues/7974#issuecomment-329250974
`
So my implementation is:
printThis = (event) => {
console.log('printing tile... '+ event.currentTarget.id);
};
<IconButton className={classes.icon} id = {tile.img} onClick={this.printThis}>
<i className="material-icons md-24 md-light" >
print
</i>
</IconButton>