I was unable to populate the with the correct array information. This is now working with the fix below.
Here is the corrected file.
renderComments(){
if (this.props.selectedDish != null) {
const commentList = this.props.selectedDish.comments;
return (
<div>
<h4>Comments</h4>
{commentList.map((comment) => {
return (
<ul className="list-unstyled" >
<li>
<p>{comment.comment}</p>
<p> -- {comment.author}{" "}
{Intl.DateTimeFormat("en-US",{
month: "short",
day: "2-digit",
year: "numeric"}).format(new Date(comment.date))}
</p>
</li>
</ul>
);
})};
</div>
);
} else {
return (
<div></div>
);
}
}
Thank you sava128
You should assign comments like you did with dish.name and dish.description
try:
renderComments() {
const dish = this.props.selectedDish;
if (dish) {
const commentList = dish.comments;
console.log("test2", commentList);
return (
<div>
<h4>Comments</h4>
<ul className="list-unstyled">
{commentList.map((comment) => {
return (
// list items here
)
})}
</ul>
</div>
);
} // else here
}
Related
I'm creating navigation for mobile devices. Everything works, but when I'm trying to open third level of navigation, it doesn't open, but collapses previous level. I dont know what to do and I'm pretty dissapointed, because it seems like easy thing and I feel like dumb. Someone have any tips please? :(
function MobileCategoriesLinks(props: MobileLinksProps) {
const { data } = useCollectionsQuery();
const { level = 0, onItemClick } = props;
const handleItemClick = (item: any) => {
if (onItemClick) {
onItemClick(item);
}
};
const linksList = data?.collections.items.map((department, index) => {
let item;
if(department.parent?.id === "1") {
const renderItem: RenderItemFn = ({ toggle, setItemRef, setContentRef }) => {
let arrow = null;
let subLinks = null;
let linkOrButton = null;
let link = "/" + department.children
if(department.children?.length) {
arrow = (
<button className="mobile-links__item-toggle" type="button" onClick={toggle}>
<ArrowRoundedDown12x7Svg className="mobile-links__item-arrow" />
</button>
);
}
let depChild = department.children?.map((name) => {
let x = name.name
let link = "/" + name.slug
let child = name
let c = child.children
if(child.children?.length) {
let thirdChild = child.children?.map((item, index) =>{
return item.name
})
let thirdChildSlug = child.children?.map((item, index) =>{
return item.slug
})
arrow = (
<button className="mobile-links__item-toggle" type="button" onClick={toggle}>
<ArrowRoundedDown12x7Svg className="mobile-links__item-arrow" />
</button>
);
subLinks = (
<div className="mobile-links__item-sub-links" ref={setContentRef}>
<ul className="mobile-links mobile--links--level--3">
<li>
<div className="mobile-links__item">
<div className="mobile-links__item-title">
{thirdChild}
</div>
</div>
</li>
</ul>
</div>
)
if(child.children?.length) {
linkOrButton = (
<AppLink
href={"/" + child.slug}
className="mobile-links__item-link"
onClick={() => handleItemClick(link)}
>
{child.name}
</AppLink>
)}
return (
<li>
<div className="mobile-links__item" ref={setItemRef}>
<div className="mobile-links__item-title">
<AppLink
href={"/" + child.slug}
className="mobile-links__item-link"
onClick={() => handleItemClick(link)}
>
{name.name}
</AppLink>
{arrow}
</div>
{subLinks}
</div>
</li>
)}
return (
<li>
<div className="mobile-links__item">
<div className="mobile-links__item-title">
{x}
</div>
</div>
</li>
);
}
)
subLinks = (
<div className="mobile-links__item-sub-links" ref={setContentRef}>
<ul className="mobile-links mobile--links--level--2">
{depChild}
</ul>
</div>
)
if(department.children) {
linkOrButton = (
<AppLink
href={"/" + department.slug}
className="mobile-links__item-link"
onClick={() => handleItemClick(link)}
>
{department.name}
</AppLink>
)} else {
linkOrButton = (
<button
type="button"
className="mobile-links__item-link"
onClick={() => handleItemClick(link)}
>
{department.name}
</button>
)
}
return (
<div className="mobile-links__item" ref={setItemRef}>
<div className="mobile-links__item-title">
{linkOrButton}
{arrow}
</div>
{subLinks}
</div>
);
};
item = <Collapse toggleClass="mobile-links__item--open" render={renderItem} />;
}
return <li key={index}>{item}</li>
}
);
return ( <ul className={`mobile-links mobile-links--level--1`}>
{linksList}
</ul>
);
}
export default withApollo(MobileCategoriesLinks)
I've been getting a "Each child in a list should have a unique key prop" error. I've read up on the documentation and put keys in, but no luck. Not sure what I'm misunderstanding!
blogPosts is imported from a context.
The ids being called as keys are unique (POSTID1, POSTID2, ...etc).
Got rid of some classnames for better readability.
const topicPosts = blogPosts.filter((post)=>post.topic.toLowerCase()===topic);
const handleLoadMore = () => {
const newIndex = articleIndex + 5 > topicPosts.length ? topicPosts.length : articleIndex + 5;
setArticleIndex(newIndex);
}
return (
<section onClick={handleOutsideClick}>
<div>
<section>
<h1>{topic}</h1>
{
topicsData.map((topicData)=> topicData.name.toLowerCase()===topic && <p key={topicData.id}>{topicData.intro}</p>)
}
</section>
<div>
<section>
<div>
{
topicPosts.slice(0,3).map((post)=>{
const { id } = post;
return (
<TopicPagePost key={id} {...post}/>
)
})
}
</div>
<div className={topicPosts.length>3 ? `subpage-articles` : `display-none`}>
{
topicPosts.slice(3,articleIndex).map((post, index)=>{
const { id } = post;
return (
<>
<TopicPagePost key={id} {...post}/>
{
index%4===0 && <div key={index} className="subpage-main-ad">
Ad placement here
</div>
}
</>
)
})
}
</div>
<button type="button" onClick={handleLoadMore}>Load more articles</button>
</section>
<aside>
<SubscribeBlock/>
<div>
Ad placement here
</div>
</aside>
</div>
</div>
</section>
)
That is because you need to add a key to the first element returned from the map, in this case <>.
To do that, you need to replace <> with a <Fragment> instead, so you can add a key directly to it:
import React, { Fragment } from "react"
{topicPosts.slice(3,articleIndex).map((post, index) => {
const { id } = post;
return (
<Fragment key={id}>
<TopicPagePost {...post}/>
{index%4===0 && (
<div className="subpage-main-ad">
Ad placement here
</div>
)}
</Fragment>
)
})}
I am trying to get my head around condtional rendering and have started trying to implment this with a anonymous function.
pseudo code
if(statement)
render this
else
render something else
The condition works if the Boolean is set to isLoggedin = true but if false it throws
Error: DisplayUserAcountDetails(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
My actual code
render() {
const isLoggedIn = false;
if (isLoggedIn)
return (
<div>
{(() => {
if (isLoggedIn) {
return (
<ul>
{this.state.AccountDetails &&
this.state.AccountDetails.map(function(
AccountDetails,
index
) {
return (
<div className="jumbotron">
<h3>Account Details</h3>
<li> Email: {AccountDetails.Email}</li>
<li> Name: {AccountDetails.NameOfUser}</li>
<li>
{" "}
Contact Number: {AccountDetails.ContactNumber}{" "}
</li>
<li>
<Link to="/profile-update-account-details">
<button>Update Account Details</button>
</Link>
</li>
</div>
);
})}
</ul>
);
} else {
return (
<div>
<div>otherCase</div>
<h1>Not there</h1>
</div>
);
}
})()}
</div>
);
}
Why is this throwing an error when one is rendered but the other loads fine? Is there some logic that I am missing?
First solution:
render() {
const isLoggedIn = false;
if (!isLoggedIn) {
return (
<div>
<div>otherCase</div>
<h1>Not there</h1>
</div>
);
}
return (
<ul>
{this.state.AccountDetails &&
this.state.AccountDetails.map(function(AccountDetails, index) {
return (
<div className="jumbotron">
<h3>Account Details</h3>
<li> Email: {AccountDetails.Email}</li>
<li> Name: {AccountDetails.NameOfUser}</li>
<li> Contact Number: {AccountDetails.ContactNumber} </li>
<li>
<Link to="/profile-update-account-details">
<button>Update Account Details</button>
</Link>
</li>
</div>
);
})}
</ul>
);
Second solution:
render() {
const isLoggedIn = false;
return (
<>
{isLoggedIn ? (
<ul>
{this.state.AccountDetails &&
this.state.AccountDetails.map(function(AccountDetails, index) {
return (
<div className="jumbotron">
<h3>Account Details</h3>
<li> Email: {AccountDetails.Email}</li>
<li> Name: {AccountDetails.NameOfUser}</li>
<li> Contact Number: {AccountDetails.ContactNumber} </li>
<li>
<Link to="/profile-update-account-details">
<button>Update Account Details</button>
</Link>
</li>
</div>
);
})}
</ul>
) : (
<div>
<div>otherCase</div>
<h1>Not there</h1>
</div>
)}
</>
);
}
1) You are missing curly braces { } of the if else statement.
2) You should check out the ternary operator in JavaScript.
I'm pretty sure you are missing a ELSE statement.
Have a look:
render() {
const isLoggedIn = false;
if (isLoggedIn)
return (
<div>
{(() => {
if (isLoggedIn) {
return (
<ul>
{this.state.AccountDetails &&
this.state.AccountDetails.map(function(
AccountDetails,
index
) {
return (
<div className="jumbotron">
<h3>Account Details</h3>
<li> Email: {AccountDetails.Email}</li>
<li> Name: {AccountDetails.NameOfUser}</li>
<li>
{" "}
Contact Number: {AccountDetails.ContactNumber}{" "}
</li>
<li>
<Link to="/profile-update-account-details">
<button>Update Account Details</button>
</Link>
</li>
</div>
);
})}
</ul>
);
} else {
return (
<div>
<div>otherCase</div>
<h1>Not there</h1>
</div>
);
}
})()}
</div>
);
else
{
return (null)
}
}
I am trying to loop through object of objects and using map to list the item and I am getting this object from redux. I can console.log the value but jsx returns nothing. I tried removing {} and return and using () only but still it is not rendering anything.
My posts object looks like
posts = { 1: {id: 1, title: "Hello world"} }
Component.js
renderList(){
const { posts } = this.props;
Object.keys(posts).map(key => {
console.log(`${key} and ${posts[key].title}`);
return (
<li key={key} className="list-group-item">
{posts[key].title}
</li>
);
});
}
render(){
return (
<div>
<h2>Posts</h2>
<ul className="list-group">{this.renderList()}</ul>
</div>
);
}
I can't figure out what I am doing wrong.
Your renderList method does not have a return statement.
Depending on if your version of React you can either return an array here or you need to wrap it in a div (or in this case put the ul into it).
renderListOnReact16(){
const { posts } = this.props;
return Object.keys(posts).map(key => {
console.log(`${key} and ${posts[key].title}`);
return (
<li key={key} className="list-group-item">
{posts[key].title}
</li>
);
});
}
renderOnReact16(){
return (
<div>
<h2>Posts</h2>
<ul className="list-group">{this.renderList()}</ul>
</div>
);
}
renderListOnReact15(){
const { posts } = this.props;
return (
<ul className="list-group">
{Object.keys(posts).map(key => {
console.log(`${key} and ${posts[key].title}`);
return (
<li key={key} className="list-group-item">
{posts[key].title}
</li>
);
})}
);
}
renderOnReact16(){
return (
<div>
<h2>Posts</h2>
{this.renderList()}
</div>
);
}
I tried to convert react js function to class but I didn't know how to convert it completely please look at this function and convert it for me correctly.
original function
code :var MailboxList = React.createClass({render: function() {
var mailbox_list = this.props.mailboxes.map(function(mailbox) {
return (
<li className="list-group-item"
key={mailbox.id}
onClick={this.props.onSelectMailbox.bind(null, mailbox.id)}>
<span className="badge">
{mailbox.emails.length}
</span>{mailbox.name}</li>);}.bind(this));
return (
<divclassName="col-md-2">
<ul className="mailboxes list-group">
{mailbox_list}</ul>
</div>);
}});
I would recommend using the most recent way to build component with babel 6.
As a Functions
export default function MailboxList({ mailboxes }) {
const mailbox_list = mailboxes.map((mailbox) =>
(
<li className="list-group-item"
key={mailbox.id}
onClick={this.props.onSelectMailbox.bind(null, mailbox.id)}
>
<span className="badge">
{mailbox.emails.length}
</span>{mailbox.name}</li>
));
return (
<div className="col-md-2" >
<ul className="mailboxes list-group">
{mailbox_list}</ul>
</div>
);
}
As a Class
export default class MailboxList extends React.Component {
renderMailboxList = () => {
return (
this.props.mailboxes.map((mailbox) => (
<li className="list-group-item"
key={mailbox.id}
onClick={this.props.onSelectMailbox.bind(null, mailbox.id)}
>
<span className="badge">
{mailbox.emails.length}
</span>
{mailbox.name}
</li>
))
)
}
render() {
return (
<div className="col-md-2" >
<ul className="mailboxes list-group">
{this.renderMailboxList}</ul>
</div>
);
}
}