How to display an image? - reactjs

I can not display the image, I do
const imgUrl = companyList.find(i => i.id === items.companyId).imgUrl;
And after creating the block, the desired picture is displayed, but it is worth updating the page, as ...
Everything is normally added to the database and should work ...
In my other file, I use the exact same method and everything works, but for some reason there isn’t ...
const getInvoiceList = () => {
return invoiceList.map(items => {
const imgUrl = companyList.find(i => i.id === items.companyId).imgUrl;
return (
<div key={items.id} className="invoice__card">
<div className="card__data">
<p>{items.invoice}</p>
<i onClick={() => onVisibleDetails(items.id)}><FiMoreHorizontal /></i>
</div>
<div className="card__body">
<div className="invoice__order">
<p>Оплатил</p>
<img src={imgUrl} alt="logo" />
</div>
<div className="invoice__order">
<h3>$2.400</h3>
<p>Сумма</p>
</div>
<div className="invoice__date">
<h3>30.01.2020</h3>
<p>Дата оплаты</p>
</div>
</div>
</div>
);
});
};
<div className="invoice__card-wrapper">
{invoiceList.length !== 0 ? getInvoiceList() : "Nety"}
</div>

Looks like your data is either incomplete, or the structure isn't matching up with the way you're trying to access it. The error Cannot read property "imgUrl" is occurring because your find() method call is not finding an object, so the imgUrl property isn't defined.
This will keep the error from occurring:
const imgUrl = (companyList.find(i => i.id === items.companyId) || {}).imgUrl;
If you want to add more info about where the companyList is coming from, we might be able to get closer to an answer.

Related

How do I pass a certain data onClick in React in this situation

Basically I have a loop that runs through "ScannedCrops" and each scannedcrop renders with a button which says "View More". I want to pass the id (Which is stored in ScannedCrop._id) and console.log that onClick.
This is the loop
<div className={styles.scannedCropsGrid}>
{
scannedCrops.map(ScannedCrop => {
return <div>
<div className={styles.center}>
<div className={styles.scannedCropsContent}>
<img src={ScannedCrop.image} alt="/" />
<div className={`${ScannedCrop.healthyBoolean ? styles.healthyPlant : styles.notHealthy}`}>
{
<p>{ScannedCrop.healthyBoolean ? "Healthy" : "Not Healthy"}</p>
}
</div>
<div className={styles.healthDesc}>
<p>{ScannedCrop.healthyBoolean ? "No Disease" : ScannedCrop.diseaseName}</p>
<p>||</p>
<p>{ScannedCrop.dateTime}</p>
</div>
<div className={styles.center}>
<button className={styles.viewMoreBtn}>
More Info
</button>
</div>
</div>
</div>
</div>
})
}
</div>
This is the onClick function in the same component.
const getId = () => {
}
What I want to do is that onClick I want to get the ScannedCrop._id and console.log it. I am kind of a beginner at this.
First of all you want to add a 'key' attribute to the parent in your map function. This can be either index or the ScannedCrop._id (if the later is always unique).
So it'll look like this:
...
{scannedCrops.map((ScannedCrop, index) => {
return <div key={index (or ScannedCrop._id if unique)} >
...
Lastly to answer your question, you first need to define your handler function and then pass it on to your button element inside the OnClick event. It should end up looking like this:
//it is a common practice to name your functions
//'handleClick', 'handleOnView' and so on. You can name it
//whatever you want
const handleGetId = (id) => console.log(id)
...
<div className={styles.center}>
<button
onClick={() => handleGetId(ScannedCrop._id)}
className={styles.viewMoreBtn}>
More Info
</button>
</div>
...
Hope that answers your question!

React - Each child in a list should have a unique 'key' prop

As my first react project, I decided to try and make a Pokedex.
I have an array of Pokemon and that I pass into a List component and use the .map() function to render. I understand that the root-most element of that the .map() function returns needs a unique key and I understand that it is ideal if the key can be truly unique to the item so that if the list is sorted, items have the same key. Therefore, I figured using the 'id' of the pokemon would be ideal. I believe I have done that but I cannot get rid of the warning in console. I'd really appreciate a hand with this.
export default class List extends React.Component {
render() {
const { list, nav } = this.props;
return (
<div className="list">
{list.map((pokemon) => (
<PokemonItem key={pokemon.id} navigation={nav} pokemon={pokemon} />
))}
</div>
);
}
}
PokemonItem Render Method
render() {
const { pokemon, navigation } = this.props;
return (
<div onClick={() => {
navigation.navigate("Details", { pokemon });
}}
className={"list-item bg_" + pokemon.types[0]}>
<div className="header">
<div className="name">{pokemon.name}</div>
<div className="id">#{this.getId(pokemon.id)}</div>
</div>
<div className="body">
<div className="types">
{pokemon.types.map((type) => {
return <div className="type">{type}</div>;
})}
</div>
<div className="sprite">
<img src={pokemon.imgURL} alt={pokemon.name} title={pokemon.name}></img>
</div>
</div>
<div className="background-image">
<img src={PkBall} alt="" />
</div>
</div>
);
}
Warning message showing in console
Checking your PokemonItem it reveals that the reason may be laying in this piece of code:
{pokemon.types.map((type) => {
return <div className="type">{type}</div>;
})}
This is easily fixed by adding the key attribute:
{pokemon.types.map((type) => {
return <div className="type" key={type.id}>{type}</div>;
})}
You need to add a key in every item returned from a map in order to avoid this error. Also I advice you to add the console output related to your question in the body so it's easier to pinpoint the errors.
After the edit of the OP's question the warning occurs here:
<div className="types">
{pokemon.types.map((type) => {
return <div className="type">{type}</div>;
})}
</div>
The key-property is not set for div and should be done like in the first method. If type is unique you can use this as key.

How to render my Modal window and all the information contained inside ( in React)?

My application renders twelve random people fetched from a different website. Everything works fine apart from my modal component(it should render more information about the person you clicked). For some reason whenever I try to render it I get this error 'Modal.js:9 Uncaught TypeError: Cannot read property 'medium' of undefined' and more errors comes with it. I am printing props.modalInfo from the Modal component to the console and it does have all the information I need, but for some reasons it shows that props.modalInfo is undefined when I try to render it. I have never done modal box in React (I am a beginner). Could someone explain me how I can render my Modal and pass all the data successfully? Thank you in advance!
handleClick(id) {
this.setState((prevState) => {
const modalInfoToPass = prevState.employeeList.filter(employee =>
{
if(`${employee.name.first} ${employee.name.last}` === id){
// get only and only one object that fulfils the
// condition
return employee;
}
})
return {
displayModal: true,
// update the modalInfo state
modalInfo: modalInfoToPass
}
})
}
render(){
return (
<div className='container'>
<Header />
<main>
{
this.state.loading ? <h2 className='load-page'>Loading...</h2> :
this.state.employeeList.map(employee =>
<Employee key={`${employee.name.title}
${employee.name.last}`}
employeeInfo={employee}
**handleClick={this.handleClick}**
/>)
}
</main>
<Footer />
**{this.state.displayModal && <Modal modalInfo={this.state.modalInfo} />}**
</div>
);
}
function Modal(props) {
**console.log(props.modalInfo);**
return (
<div className='bg-modal'>
<div className='modal-content'>
<div className='modal-image'>
<img src={props.modalInfo.picture.medium} alt={`${props.modalInfo.name.title} ${props.modalInfo.name.first}`}/>
</div>
<div className='modal-info'>
<p className='name'>{props.modalInfo.name.first} {props.modalInfo.name.last}</p>
<p className='email'>{props.modalInfo.email}</p>
<p className='place'>{props.modalInfo.location.city}</p>
</div>
<hr />
<div className='modal-more-info'>
<p className='number'>{props.modalInfo.cell}</p>
<p className='address'>{`${props.modalInfo.location.street}, ${props.modalInfo.location.state}`}</p>
<p className='postcode'>{props.modalInfo.location.postcode}</p>
<p className='birthday'>{props.modalInfo.dob.date}</p>
</div>
</div>
</div>
);
}
What is id and is it on an employee? If it isn't available, you could just pass what you're filtering for in your handleClick:
handleClick={()=>this.handleClick(`${employee.name.first} ${employee.name.last}`)}
Or, you could just pass the employee:
handleClick={()=>this.handleClick(employee)}
and modify your handler:
handleClick(employee) {
this.setState({modalInfo: employee, displayModal: true})
}

Reactjs: Replying comments not working in reactjs

Replying comments not working in reactjs.
Believe I have search through this venerable forum but most solution found could not resolve my issue.
This code works fine by displaying post and its corresponding comments from an array. Great Thanks to Stackoverflow Engineer Ryan for his help. Now I want to display each reply made on each comments as per code below
{props.comment.replys.map((reply, i) => (<div>{reply.reply}</div>))}
but it shows error
Cannot read property 'replys' of undefined
at Post
In angularjs I can just implement code below inside Post ng-repeat function.
<div class="post" ng-repeat='post in posts'>
<div>
{{ post.content }}
</div>
<!-- Comments -->
<div ng-repeat='comment in post.comments'>
<div class='comment'>{{ comment.comment }} <b>{{ comment.id }}</b></div>
<div ng-repeat='reply in comment.replys'>
<div>{{ reply.reply }}</div></div>
</div>
</div>
Here is the updated code in reactjs.
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
const Post = (props) => {
console.log(props.post);
console.log(props.comments);
return (<React.Fragment><li >
{props.post.id} - {props.post.content}
</li>
<div>
{props.post.comments.map((comment, i) => (<div>{comment.comment} --- {comment.id}</div>))}
{props.comment.replys && props.comment.replys.map((reply, i) => (<div>{reply.reply}</div>))}
</div>
</React.Fragment>
);
};
class Comment extends React.Component {
constructor(props) {
super(props);
this.state = {
rec: [
{"id":"1","content":"first post","comments":[{"comid":"1","comment":"first comment","replys":[{"reply":"first comment reply1"},{"reply":"first comment second reply"}] }]},
{"id":"2","content":"second post","comments":[{"comid":"2","comment":"second comment", "replys":[{"reply":"second comment reply1"}] }]}
],
};
}
render() {
return (
<div>
<h3>Records</h3>
<ul>
{this.state.rec.map((post, i) => (
<Post post={post} key={i}/>
))}
</ul>
</div>
);
}
}
const Post = (props) => {
return (<React.Fragment>
<li>
{props.post.id} - {props.post.content}
</li>
<div>
{props.post.comments.map((comment, i) => (
<div key={"comment_" + comment.id}>
<div>{comment.comment} --- {comment.id}</div>
{comment.replys && comment.replys.map((reply, i) => (<div>{reply.reply}</div>))}// Here
</div>
))}
</div>
</React.Fragment>
);
};
You can take replays data in this way.
One comment on your second post in the sample data has no replies (replys) so it's quite expected that you see that error: you call map on undefined.
Try this instead (check if we have replies first and only map if some exist):
{props.comment.replys && props.comment.replys.map((reply, i) => (<div>{reply.reply}</div>))}
Edit
Here's one implementation of the Post method (I renamed it to renderPosts, you should do the same) that should work (better):
const renderPosts = (props) => {
return (
<>
<li>
{props.post.id} - {props.post.content}
</li>
<div>
{props.post.comments.map((comment) => {
return (
<div key={comment.comid}>
<div>{comment.comment} --- {comment.id}</div>
{comment.replys && comment.replys.map((reply) => <div key={reply.reply}>{reply.reply}</div>)}
</div>
)
})}
</div>
</>
);
};
Note that I've:
- replaced the outer element with the shorter notation for fragments
- moved the iteration of the replies inside of the iteration of the comments (each comment has a list of replies)
- added the mandatory key attribute (you should add an id to the replies on your datamodel, I used the reply.reply value for the moment but that's in general a bad id, because there's no guarantee that all replies are different)
Hope it helps!

How to have backup URL show if the JSON data is undefined?

const SearchResults = ({ artists }) => (
<div className="search-results">
{artists.map(val => (
<a href="# " key={uniqid()}>
<h3>{val.name}</h3>
<img
className="box-img"
src={
val.images[0].url
? val.images[0].url
: 'https://www.w3schools.com/w3css/w3css_images.asp'
}
alt=""
/>
</a>
))}
</div>
);
I have an API call going to Spotify to get a list of Artist. When the results all have an image there is no problem but if they don't, React just returns undefined and I can't figure out how to have the placeholder image show.
You can simply have a bare png default image for this in your project, then import it and use it when no image is returned from spotify, something like:
import defaultArtistImage from './myProject/assets/images/defaultArtistImage.png';
...
const SearchResults = ({ artists }) => (
<div className="search-results">
{artists.map(val => (
<a href="# " key={uniqid()}>
<h3>{val.name}</h3>
<img
className="box-img"
src={
val.images.length !== 0
? val.images[0].url
: defaultArtistImage
}
alt=""
/>
</a>
))}
</div>
);
this is simpler than retrieving the image from an external server. Also, doing val.images[0].url can give you an error if .images it's an empty array

Resources