react render div if loop was empty - reactjs

I am rendering a list and I want to show an info that data was not loaded.
Here is my code:
<div className="dashboard-table dashboard-table-done">
<div className="dashboard-table-title dashboard-table-title-done">Chamadas encerradas</div>
{ this.state.data && this.state.data.map(attendInfo =>
attendInfo.close && (
<DashboardAttend {...attendInfo} />
)
)}
If attendInfo.close then renders <DashboardAttend>
If no one was rendered I want to render a message saying that no one data was rendered like:
<div>No one data was found</div>
I can't use this.state.data because the field close can be null and length can be higther than 0

How about something like this
render(){
const dataForRender = this.state.data? this.state.data.filter((attendInfo) => {
return attendInfo.close;
}): [];
return (
<div className="dashboard-table dashboard-table-done">
<div className="dashboard-table-title dashboard-table-title-done">
Chamadas encerradas
</div>
{
dataForRender.length>0 ? dataForRender.map(attendInfo =>
(
<DashboardAttend {...attendInfo} />
)
): <div>No one data was found</div>
}
</div>
);
}

I think what you are asking is if state.data is empty or contains no elements, then you want to write:
<div>No one data was found</div>
You can do this by simple adding another bit to the end:
{ (!state.data || !state.data.length) && <div>No one data was found</div> }
So in position it would look something like:
<div className="dashboard-table dashboard-table-done">
<div className="dashboard-table-title dashboard-table-title-done">Chamadas encerradas</div>
{ this.state.data && this.state.data.map(attendInfo =>
attendInfo.close && (
<DashboardAttend {...attendInfo} />
)
)}
{ (!state.data || !state.data.length) && <div>No one data was found</div> }

Related

How to include a wrapper element if there are items in a collection?

I'm obviously not doing this the React way.
I have a collection of comparison objects that are shown
if there is more than one, then I want to include a wrapper element around this collection
In Vue.js I would do this with a v-show or v-if for instance. How do I do this in React?
{/* COMPARISONS */}
{this.getCurrentItem().comparisons!.length > 0 &&
(
<div className="comparisonAreas">
)
}
{
this.getCurrentItem().comparisons!.map((comparison: IComparison) => {
return (
<div className="comparison">
<h3 dangerouslySetInnerHTML={{ __html: this.getSmartVersusLine(comparison, this.getCurrentItem()) }} />
<div dangerouslySetInnerHTML={{ __html: this.convertComparisonBodyToBodyParsed(comparison) }} />
</div>
)
})
}
{this.getCurrentItem().comparisons!.length > 0 &&
(
</div>
)
}
Extract the middle into a variable before and then render the two cases:
const MyComp = (props) => {
const comparisonObjects = ...
if(comparisionObjects.length <= 1) {
return comparisonObjects
} else {
return <div>{comparisonObjects}</div>;
}
}
Edit: You should add a key prop in your array components. See https://reactjs.org/link/warning-keys
You could use a ternary operator :
{this.getCurrentItem().comparisons!.length>0 ?
<div className="comparisonAreas">getCurrentItem.comparisons!.map...</div>
: getCurrentItem.comparisons!.map...
}

ReactJS Conditional rendering is not working

I have an input and whenever a user clicks in the box I want to see if the input is greater than 1
updateQuery(e) {
this.setState({ query: e.target.value });
const optionValue = e.target.value.length;
}
Then I want to do the following in render / return:
render() {
const { query } = this.state;
return (
<div>
{optionValue > 1 ? (
<div className="loading">
) : (
<div className="not-loading">
)}
<NewSearch query={query} updateQuery={this.updateQuery} />
</div>
<Debounce ms={1000}>
<BusInfo query={query} />
</Debounce>
</div>
);
}
But I get this issue:
Line 48:6: Parsing error: Unexpected token ;
and my app won't run.
What am I missing here?
I've read this doc:
https://reactjs.org/docs/conditional-rendering.html
Help!
It seems that the only thing you need to change based a certain value of optionValue is the className of the div.
Hence, you can do something like this:
return (
<div>
<div className={optionValue > 1 ? 'loading' : 'not-loading'}>
<NewSearch query={query} updateQuery={this.updateQuery} />
</div>
<Debounce ms={1000}>
<BusInfo query={query} />
</Debounce>
</div>
);
Also, optionValue is a const of updateQuery and cannot be accessed later on your render. You should also add optionValue on your state:
updateQuery(e) {
this.setState({
query: e.target.value,
optionValue: e.target.value.length
});
}
And later on your render:
const { query, optionValue } = this.state;
or just check on your render query.length instead of holding a new value just for this on your state.
In case you have classes that you want to share on both cases, you could use template literals to achieve this:
<div className={`myClass1 myClass2 ${optionValue > 1 ? 'loading' : 'not-loading'}`}>
Don't define html tag like react component
Change this
{optionValue > 1 ? (
<div className="loading">True condition</div>
) : (
<div className="not-loading">False condition</div>
)}
Your opening and closing tags don't match up, you have an unmatched closing </div>
If the conditionally rendered divs don't have any content, that's fine but they do need to be self-closing: <div className="loading" /> (note the closing />)
This should now work fine (although you may need to do this.optionValue)
updateQuery(e) {
this.setState({ query: e.target.value });
this.optionValue = e.target.value.length;
}
render() {
const { query } = this.state;
return (
<div>
<div>
{this.optionValue > 1 ? (
<div className="loading" />
) : (
<div className="not-loading" />
)}
<NewSearch query={query} updateQuery={this.updateQuery} />
</div>
<Debounce ms={1000}>
<BusInfo query={query} />
</Debounce>
</div>
);
}

How to render only the 3rd object from an array react

React newbie here. I have a component which gets an array of objects in JSON format and saves it into the state.
I am now unsure how I can render the name/description of only the 3rd object in the components render function.
I want to be able to only render the 1,2,3,4,5th object etc as well.
Any ideas?
https://codesandbox.io/s/admiring-ishizaka-rfp3k - Demo
return (
<div className="App">
{name1} // Object 1 name
{description1} // Object 1 description
{name2} // Object 2 name
{description2} // Object 2 description
</div>
);
To give you the basic idea, you can display the name of your 3rd component on your render like this:
render() {
return (
<div className="App">
{this.state.profiles.map((item, index) => {
return(
index === 2 ? item.name : ""
)
})}
</div>
);
}
Please use Array map
render() {
const { profiles } = this.state;
return (
<div className="App">
{
profiles.map(profile => (
{profile.name}
{profile.description}
))
}
</div>
);
}
render() {
return (
<div className="App">
{this.state.profiles.map((data, i) => {
return(
i=== 2 ? (<p>{data.name}</p>) :(<p> </p>)
)
})}
</div>
);
}

Rendering Parameterized Function Results

I have a function that I am using to check if there are results from a page load and if there are, then map the array and return a component and if there aren't then return a string stating there are no results. At the moment I have been able to write the function without any issue, but I can't seem to get return statement to load. Am I following the right path to returning the components or is there a better method?
The console logs return the correct info, but everything in the return() isn't appearing in the view.
export default class BlogKanbanLayout extends React.Component {
constructor(props) {
super(props);
this.resultsCheck = this.resultsCheck.bind(this);
}
resultsCheck(blogs, user) {
console.log("resultsCheck")
console.log(blogs)
console.log(blogs.length)
if(blogs.length === 0) {
<p>There are no results for your filter criteria.</p>
} else {
console.log("There are blog results")
console.log(blogs)
console.log(user)
blogs.map((blog, index) => {
console.log("blog map")
console.log(blog)
return (
<div className="row">
<p>This is a test></p>
<BlogKanbanCard {...blog} key={blog.blogIdHash} user={user} />
</div>
)
})
}
}
render() {
return (
<div className="col-md-12">
{this.resultsCheck(this.props.negativeBlogs, this.props.user)}
</div>
)
}
}
In your resultsCheck you forgot to return the result of your mapping.
Also, the key used in the map function needs to be given to parent element, which here is your div.
And using conditional rendering you can reduce your entire component to the following code for te exact same result :
export default class BlogKanbanLayout extends React.Component {
render() {
const { negativeBlogs, user } = this.props
return (
<div className="col-md-12">
{negativeBlogs.length ?
negativeBlogs.map(blog =>
<div className="row" key={blog.blogIdHash}>
<p>This is a test></p>
<BlogKanbanCard {...blog} key={blog.blogIdHash} user={user} />
</div>
)
:
<p>There are no results for your filter criteria.</p>
}
</div>
)
}
}
And since you are not using the state of your component you could even optimize it to a stateless one :
const BlogKanbanLayout = ({ negativeBlogs, user }) =>
<div className="col-md-12">
{negativeBlogs.length ?
negativeBlogs.map(blog =>
<div className="row" key={blog.blogIdHash}>
<p>This is a test></p>
<BlogKanbanCard {...blog} key={blog.blogIdHash} user={user} />
</div>
)
:
<p>There are no results for your filter criteria.</p>
}
</div>
You resultsCheck method need to return something, so you need to add the return statement before the two results
resultsCheck(blogs, user) {
console.log("resultsCheck")
console.log(blogs)
console.log(blogs.length)
if(blogs.length === 0) {
return <p>There are no results for your filter criteria.</p>
} else {
console.log("There are blog results")
console.log(blogs)
console.log(user)
return blogs.map((blog, index) => {
console.log("blog map")
console.log(blog)
return (
<div className="row">
<p>This is a test></p>
<BlogKanbanCard {...blog} key={blog.blogIdHash} user={user} />
</div>
)
})
}
}

Extra div wrapper in map function

i need to create extra div wrapper for second and third element in React
I use a map function and i dont know how to fix it.
Here is a sandbox https://codesandbox.io/s/ojz6lvqnp6
And here is a what i need to achive
Another screen:
You need to change your code in your render method to
if (index !== 0) {
return (
<div key={index} className="second_wrapper">
<h1 >{index}</h1>
</div>
);
} else ....
EDIT:
You would need to change your code to :
render() {
const { members } = this.state;
return (
<div>
<div className="first_wrapper">
<h1 key={0}>{members[0].name}</h1>
</div>
<div className="second_wrapper">
{members.map((m, i) => {
if (i > 0) return <h1 key={i}>{m.name}</h1>;
})}
</div>
</div>
);
}
The new sandbox

Resources