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
I have used conditional rendering in the past but for some reason, it's working on one element here but not on another although they are both using the same JSON phrasing and the same type of conditional rendering?
JSON array
//Adobe component data
export default[
{
workName: 'Switch up your "Grub" Motiongraphic',
workDescription: 'This is a motion graphic comparing the environmental and health effects of consuming animal products compared to insects as dietary source of protein.',
workTech: ['Adobe After effects'],
videoAddress: ['https://youtu.be/cloat51hzDY'],
Images: []
},
{
workName: 'Simplyfit concept poster',
workDescription: 'This is a poster developed explaining the concept of Simplyfit, a fitness application developed as part of my final year project.',
workTech: ['Adobe Illustrator'],
videoAddress: [],
Images: ['SFPoster.jpg'],
},
{
workName: 'Switch up your "Grub" Infographic',
workDescription: 'This is an infographic developed explaining the benefits of consuming insects as a source of protein.',
workTech: ['Adobe Illustrator'],
videoAddress: [],
Images: ['insectMotiongraphic.png'],
},
{
workName: 'Crunchy Nut Advert spoof',
workDescription: 'This video was made as a comedic spoof of a Crunchy Nut advert',
workTech: ['Adobe Premier Pro'],
videoAddress: ['https://youtu.be/y8S2RUYrLN8'],
Images: [],
},
{
workName: 'Icons and Designs',
workDescription: 'These are a selection of logos and icons created by me.',
workTech: ['Adobe Premier Pro'],
videoAddress: [],
Images: ['Mylogo.png'],
},
]
The problem I'm having is with the 'videoAdress' and the 'Images' I've tried setting null values undefined etc for them both but for the images the only thing that stops them from rendering is setting the value as [] but this doesn't work for the videoAdress the iframe is still rendered?
React js code
{Data.map((Projects, index) => {
return <div className='Cards'>
<Carousel showThumbs={false} infiniteLoop={true} swipeable={false} emulateTouch={false} showStatus={false} autoPlay={slideShow} dynamicHeight={false}>
{Projects.Images && Projects.Images.map((Image, index) => { return <div className='image-iframeContainer'><img src={require("../assets/Port-images/Adobe/" + Image)} /></div> })}
{Projects.videoAddress && <div className='image-iframeContainer'><ReactPlayer url={Projects.videoAddress} muted={false} controls={false} onPlay={autoplayChange} onPause={autoplayChange} onEnded={autoplayChange} /></div>}
</Carousel>
{Projects.webAddress && <div className='webButton'><LinkIcon onClick= { () => {window.open(Projects.webAddress);}}/></div>}
<h1>{Projects.workName}</h1>
{Projects.workTech.map((Tech, index) => { return <p className='techList'>{Tech}</p> })}
<div className='descriptionContainer'>
<p className='description'>{Projects.workDescription}</p>
</div>
</div>
})}
The function I would like is for the Images and Videos only to render if there is a stored address I'm sure I'm missing something very silly but still, I've been stuck on this for awhile.
Conditional rendering works by casting the condition to a truthy value. For example:
Projects.Images && <Component />
is equal to this:
!!Project.Images && <Component />
Now if you do this for an empty array [], the truthy value is TRUE. This means that <ReactPlayer /> is rendered with [] value and the <img /> is not rendered because [].map() doesn't run on an empty array.
To fix this do this instead:
{Projects.Images && Projects.Images.length > 0 && Projects.Images.map((Image, index) => {
return <div className='image-iframeContainer'>
<img src={require("../assets/Port-images/Adobe/" + Image)} />
</div>
})}
{Projects.videoAddress && Projects.videoAddress.length > 0 &&
<div className='image-iframeContainer'>
<ReactPlayer url={Projects.videoAddress[0]} muted={false} controls={false} onPlay={autoplayChange} onPause={autoplayChange} onEnded={autoplayChange} />
</div>}
I noticed that your videoAddress doesn't use the map() method, but I guess it's a typo
I want to be able to sort my column based on ascending or descending numbers. I don't totally understand the way to do this. The online documentation shows that a Menu must be added to the table, but how does the menu know to affect which column.
This is the current way I have my BluePrintJS table implemented. I want to make the values sortable ascending or descending for any column
<Table enableFocusedCell="true" numRows=10 class="bp3-html-table bp3-table-resize-horizontal">
<Column
columnHeaderCellRenderer={() => (
<ColumnHeaderCell name="Name" />
)}
cellRenderer={i => (array.data[i] ? (<Cell>{array.data[i].name}</Cell>)
: (<Cell />))
}
/>
<Column
columnHeaderCellRenderer={() => (
<ColumnHeaderCell name="Ins" />
)}
cellRenderer={i => (array.data[i] ? (<Cell>{array.data[i].ins}</Cell>
) : (<Cell />))
}
/>
</Table>
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>
I'm trying to make this into a react component so I can use it in my website:
I don't know how to go about making this or, if any libraries are involved, I don't know which ones.
it looks like this component will take a few properties:
const CardsDisplay = ({numCards}) => { /* ... */ }
const AvatarDisplay = ({imageUrl, numCards, name, score, popupMenu }) =>
<div style={{textAlign: 'center'}}>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<img src={imageUrl} />
<CardsDisplay numCards={numCards} />
</div>
{name}
<br />
{score.toLocaleString()}
<popupMenu style={{float: 'right'}} />
</div>