Why does the if in this example, cause my react component not to compile.
How would one put a if like this in the map function then?
{this.props.medication.map((object, i) => (
if(object.med_type){
<div>
<div className="col-sm-6 col-md-6">{object.item.description}</div>
<div className="col-sm-6 col-md-6">{(object.med_assigneddate !== '' && object.med_assigneddate !== null) ? object.med_assigneddate : 'N/A'}</div>
</div>
}
))}
Arrow functions can have, on the right-hand side of the => symbol either:
A block
A statement (which gets an implicit return ahead of it)
If you want an if statement with its own block, you need to write the function body as a block and explicitly include the return statement.
(object, i) => {
if (object.med_type) {
return (
<div>
<div className="col-sm-6 col-md-6">{object.item.description}</div>
<div className="col-sm-6 col-md-6">{(object.med_assigneddate !== '' && object.med_assigneddate !== null) ? object.med_assigneddate : 'N/A'}</div>
</div>
);
}
}
It could be better filter first and then use the map. You have to return something from map scope. For sample:
{this.props.medication.filter(object => (object.med_type)).map((object, i) => (
return (
<div>
<div className="col-sm-6 col-md-6">{object.item.description}</div>
<div className="col-sm-6 col-md-6">{(object.med_assigneddate !== '' && object.med_assigneddate !== null) ? object.med_assigneddate : 'N/A'}</div>
</div>);
))}
Related
I want to display a div layer if list if empty into React page. I tried this:
{(() => {
if (!ordersList && ordersList.length === 0) {
return (
<div className="alert alert-warning">No Orders found</div>
)
}
})()}
But it's not working. What is the proper way to implement this?
The condition is incorrect. If list is empty, then !ordersList will be false.
So, the <div> won't be rendered.
You may try this:
{(() => {
if (!ordersList || ordersList.length === 0) {
return (
<div className="alert alert-warning">No Orders found</div>
)
}
})()}
Or even simpler:
{
(!ordersList || ordersList.length === 0) &&
<div className="alert alert-warning">No Orders found</div>
}
If I understand you correctly, you want to conditionally render a div when ordersList (a variable/state that I presume is in your component) is empty. Then add this to your JSX returned by your component.
{!ordersList.length && <div className="alert alert-warning">No Orders found</div>}
I am working on a project as a means to practice some stuff in react and I need to render a button for each of the map data. I did this successfully but expand and collapse has been giving me issue. Whenever I click on the button all data collapse and expand together.
const DataFetch = () => {
...
const [btnValue, setBtnValue] = useState('+');
const handleChange = (e) => {
setShowData(!showData);
setBtnValue(btnValue === '+' ? '-' : '+');
};
return (
<div className='container'>
...
{studentResults
.filter((val) => {
if (searchTerm === '') {
return val;
} else if (
val.firstName.toLowerCase().includes(searchTerm.toLowerCase()) ||
val.lastName.toLowerCase().includes(searchTerm.toLowerCase())
) {
return val;
} else {
return null;
}
})
.map((student) => {
return (
<div key={student.id}>
<div className='card'>
<div className='row'>
<div className='col-2'>
<div className='pic'>
<img src={student.pic} alt='avatar' />
</div>
</div>
<div className='col'>
<div className='details'>
<p className='name'>
{student.firstName.toUpperCase()}{' '}
{student.lastName.toUpperCase()}
</p>
<div className='sub-details'>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>
Average:{' '}
{student.grades.reduce(
(a, b) => parseInt(a) + parseInt(b),
0
) /
student.grades.length +
'%'}
</p>
<button onClick={handleChange} className='showBtn'>
{btnValue}
</button>
{showData && (
<div>
<br />
{student.grades.map((grade, key) => {
return (
<p key={key}>
Test {key + 1}: {grade}%
</p>
);
})}
</div>
)}
...
Collapse Image
Expand Image
All the elements expand and collapse together because you assign to all of them the same state showData state.
One solution would be to add a new field to your data (so inside student) that is true or false when you want to expand or collapse the single student.
Another solution would be to create the showData state as an array where each element correspond to a different student. When you click the button, in this case, you pass to the function for example the id and with that you link your student to the right element inside the showData.
I have this array.map() arrow function and have the following error:
"Array.prototype.map() expects a value to be returned at the end of arrow function array-callback-return"
Here is my code:
{productList.map((val) => {
const category = val.CategoryName;
// const quantity = val.ProductQuantity
if (category === "MotorcycleParts") {
if (val.ProductQuantity !== 0) {
return (
<div>
<div>
<div class="buyNowBtnDiv">
{localStorage.getItem("username") === "" ||
localStorage.length === 0 ? (
<div id="buyAddBtn">
</div>
) : (
<div id="buyAddBtn">
</div>
)}
</div>
</div>
</div>
);
}
}
})}
I have read about the error and I see it has something to do with requiring a returning value, but I do have this?
A code example with a fix would help, I think it would be something simple.
You could just return null when the listed conditions are not matched:
{productList.map((val) => {
const category = val.CategoryName;
// const quantity = val.ProductQuantity
if (category === "MotorcycleParts") {
if (val.ProductQuantity !== 0) {
return (
<div>
<div>
<div class="buyNowBtnDiv">
{localStorage.getItem("username") === "" ||
localStorage.length === 0 ? (
<div id="buyAddBtn">
</div>
) : (
<div id="buyAddBtn">
</div>
)}
</div>
</div>
</div>
);
}
return null;
}
})}
map has to return a value for each item.
If you want to do some filtering, you should consider using Array.prototype.filter() before, so you can remove the ifs in your map.
The code is also way more easy to read.
{productList.filter(val => val.CategoryName === "MotorcycleParts" && val.ProductQuantity !== 0)
.map((val) => {
return (
<div>
<div>
<div class="buyNowBtnDiv">
{localStorage.getItem("username") === "" ||
localStorage.length === 0 ? (
<div id="buyAddBtn">
</div>
) : (
<div id="buyAddBtn">
</div>
)}
</div>
</div>
</div>
);
})}
I am making an application in React JS. It consists of list of the user for which book is available, taken or requested, but when the book is filtered from the store based on user the line of the invalid user still arrives.
return (
<div>
<h1>List of Books</h1>
{filterValues.map((books) => (
<Segment.Group key={books.id}>
{(books.name === user!.username || books.name === null) &&
(books.requestedBy === user!.username ||
books.requestedBy === null) ? (
<Segment>
<Item.Group>
<Item>
{console.log(books)}
<Item.Image size="tiny" circular src="/assets/books.jpg" />
<Item.Content>
<Item.Header as="a">{books.bookName}</Item.Header>
<Item.Description>
{books.isRequested ? (
<Button
name={books.bookName}
loading={target === books.bookName && submitting}
onClick={(e) => onRequestClick(e, "cancel", books.id)}
color="red"
type="button"
content="Cancel Request"
/>
) : books.isTaken ? (
<div>
<Label basic color="red">
This book is taken By you
</Label>
<Button
name={`return${books.bookName}`}
loading={
target === "return" + books.bookName && submitting
}
color="brown"
onClick={(e) => returnBook(e, books.id)}
type="button"
content="Return this Book"
/>
</div>
) : (
<Button
name={books.bookName}
loading={target === books.bookName && submitting}
onClick={(e) =>
onRequestClick(e, "request", books.id)
}
color="green"
type="button"
content="Request For Book"
/>
)}
</Item.Description>
</Item.Content>
</Item>
</Item.Group>
</Segment>
) : null}
</Segment.Group>
))}
<Segment clearing></Segment>
</div>
);
For example for the list of books i filtered 5 books in map and UI is something like :
How Can i remove those line
Your filtering logic is placed within the .map prototype method itself, so when you are returning null, it's still placed within an empty <Segment.Group> element. Therefore I guess that this element provides the styles which result in rendering those lines.
If you want to truly filter the results and omit any returns for the ones that do not match, it would be best to first call .filter() on your array and omit the null values returned by map:
{
filterValues
.filter(books =>
(books.name === user!.username || books.name === null)
&& (books.requestedBy === user!.username || books.requestedBy === null)
).map(books =>
<Segment.Group key={books.id}>
// Segment items here without the conditional rendering of elements
</Segment.Group>
)
}
I think this is because you are checking under <Segment.Group:
{filterValues.map(books => (
<Segment.Group key={books.id}>
{((books.name === user!.username || books.name === null) && (books.requestedBy === user!.username || books.requestedBy === null))
? /* CREATE THE ITEM */
: null
}
</Segment.Group>
))}
Thus, when it is evaluated to null, it still creates a <Segment.Group> which is shown as empty item in UI.
I have working code
const products = this.state.products.map((product, i) =>
product.fields.company.fields.slug === this.props.match.params.slug ?
<Suspense key={i} fallback={<div>Loading...</div>}>
<ProductListItem id={i} key={i} product={product} />
</Suspense>
: null)
return(
<div className="partner-details" style={partnerD}>
<div className="container-xl">
<Button type="button" className="btn btn-secondary" onClick={this.props.history.goBack}>
<i className="fa fa-arrow-left"></i> Get back
</Button>
<ul>
<div className="product-item">
{products}
</div>
</ul>
</div>
</div>
)
But the problem is if product.fields.company.fields.slug (company.fields.slug) does not exist my code crashes.
How can I add extra ternary operator to check if it product.fields.company exist before execute this product.fields.company.fields.slug === this.props.match.params.slug
Thanks!
if your environment has support for optional chaining you can do this
product?.fields?.company?.fields?.slug === this.props.match.params.slug ? .. : ..
otherwise you need to check that each field is truthy
product && product.fields && product.fields.company && product.fields.company.fields && product.fields.company.fields.slug === this.props.match.params.slug ? .. : ..
Use optional-chaining ( Babel plugin )
product.fields?.company?.fields?.slug
Or make use of the || operator :
(((product.fields || {}).company || {}).fields || {}).slug
And consider wrapping your compoennt in an error boundary so your app won't crash when there's this kind of errors.
In line 2 you can do:
(product && product.fields && product.fields.company && product.fields.company.fields && product.fields.company.fields.slug && this.props && this.props.match && this.props.match.params && this.props.match.params.slug && product.fields.company.fields.slug === this.props.match.params.slug) ?
or use optional chaining.