Not able to display list items using map in reactjs? - javascript

I have a userlist which contains name and email id of each user. I want to display it using the .map() method on userlist state variable. I have created displayusers() function to display the users but I am getting failed to compile error.
Code:
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state = {
userlist:[
{'name':'Rohan Singh',
'email':'rohan#gmail.com'
},
{'name':'Mohan Singh',
'email':'mohan#gmail.com'
},
{'name':'Rakesh Roy',
'email':'rakesh#gmail.com'
},
{'name':'Sunil Shah',
'email':'sunil#gmail.com'
}]
}
}
displayusers(){
return this.state.userlist.map( user => {
return(
<div className="item-card">
<div className="sub">
<div className="type">Username: {user.name}</div>
<div className="members">Email: {user.email}</div>
</div>
<div className="del-wrap">
<img src={require("../../images/cancel.svg")}/>
</div>
</div>
);
})
}
render() {
return(
<div className="users-wrap">
<h1>Users</h1>
<div className="task-content">
<div className="user-wrap">
<div className="users">
{this.displayusers()}
</div>
</div>
</div>
</div>
);
}
}
export default App;

I think you forgot about adding a key attribute to the element and there's missing </div> closing tag in your map function.
See the corrected code:
displayusers(){
return this.state.userlist.map( user => {
return(
<div className="item-card" key={user.name}>
<div className="sub">
<div className="type">Username: {user.name}</div>
<div className="members">Email: {user.email}</div>
</div>
<div className="del-wrap">
<img src={require("../../images/cancel.svg")}/>
</div>
</div>
);
});
}

You need to bind your displayusers function to this. You can do that in the constructor.
Update your code as following:
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state = {
userlist:[
{'name':'Rohan Singh',
'email':'rohan#gmail.com'
},
{'name':'Mohan Singh',
'email':'mohan#gmail.com'
},
{'name':'Rakesh Roy',
'email':'rakesh#gmail.com'
},
{'name':'Sunil Shah',
'email':'sunil#gmail.com'
}]
};
this.displayusers = this.displayusers.bind(this); // you need to add this line
}
displayusers(){
return this.state.userlist.map((user, index) => {
return(
<div className="item-card" key={index}>
<div className="sub">
<div className="type">Username: {user.name}</div>
<div className="members">Email: {user.email}</div>
</div>
<div className="del-wrap">
<img src={require("../../images/cancel.svg")}/>
</div>
);
})
}
render() {
return(
<div className="users-wrap">
<h1>Users</h1>
<div className="task-content">
<div className="user-wrap">
<div className="users">
{this.displayusers()}
</div>
</div>
</div>
</div>
);
}
}
export default App;

Related

A modal inside a Map Function In ReactJs has error message

I would like to ask question about some kind of grid gallery for a portfolio section. Each grid has a overlay which could be triggered by mouseover and the grids are generated by a map function and data in the grids are linked with a json file. The problem is that when I put a draft modal that I supposed it is for the grid , an error message showed "TypeError: Cannot read property 'toggleModal' of undefined" for this tag . Thanks for any solution.
import React, { Component } from 'react';
import Modal from './Modal';
class Portfolio extends Component {
constructor(props) {
super(props);
this.state = { isOpen: false };
}
toggleModal = () => {
this.setState({
isOpen: !this.state.isOpen
});
}
render() {
if(this.props.data){
var projects = this.props.data.projects.map(function(projects){
var projectImage = 'images/portfolio/'+projects.image;
return <div key={projects.title} className="columns portfolio-item">
<div className="item-wrap">
<a href={projects.url} className="open-popup" title={projects.title}>
<img alt={projects.title} src={projectImage} />
<div className="overlay">
<div className="portfolio-item-meta">
<h5>{projects.title}</h5>
<p>{projects.category}</p>
</div>
</div>
<div className="link-icon"><i className="fa fa-link"></i></div>
</a>
</div>
<button onClick={this.toggleModal}>
Open the modal
</button>
<Modal show={this.state.isOpen} onClose={this.toggleModal} >
Here's some content for the modal
</Modal>
</div>
})
}
return (
<section id="portfolio">
<div className="row">
<div className="twelve columns collapsed">
<h1>Check Out Some of My Works.</h1>
<div id="portfolio-wrapper" className="bgrid-quarters s-bgrid-thirds cf">
{projects}
</div>
</div>
</div>
</section>
);
}
}
export default Portfolio;
and the Modal.js is below:
import React from 'react';
import PropTypes from 'prop-types';
class Modal extends React.Component {
render() {
// Render nothing if the "show" prop is false
if(!this.props.show) {
return null;
}
// The gray background
const backdropStyle = {
position: 'fixed',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'rgba(0,0,0,0.3)',
padding: 50
};
// The modal "window"
const modalStyle = {
backgroundColor: '#fff',
borderRadius: 5,
maxWidth: 500,
minHeight: 300,
margin: '0 auto',
padding: 30
};
return (
<div className="backdrop" style={backdropStyle}>
<div className="modal" style={modalStyle}>
{this.props.children}
<div className="footer">
<button onClick={this.props.onClose}>
Close
</button>
</div>
</div>
</div>
);
}
}
Modal.propTypes = {
onClose: PropTypes.func.isRequired,
show: PropTypes.bool,
children: PropTypes.node
};
export default Modal;
The error is caused from this line:
var projects = this.props.data.projects.map(function(projects){
Since you used this.toggleModal inside this function, the this context is linking to this function, not the React component.
The solution is to use an arrow function like this:
var projects = this.props.data.projects.map((projects) => {
On a side note, it's not a good idea to define a variable inside a block and use it outside of it.
This is my revised version, thanks. What should I do if I want to add next and previous function in modal in order to show next or previous project information? Thanks. I am sorry that I am new with React and Javascript.
import React, { Component } from 'react';
import Modal from './Modal';
class Portfolio extends Component {
constructor(props) {
super(props);
this.state = {
isOpen: false,
activeProjects:"",
activeProjectImage:""
};
}
toggleModal = (projects,projectImage) => {
this.setState({activeProjects:projects, activeProjectImage:projectImage},() =>
this.setState({
isOpen: !this.state.isOpen
}));
}
render() {
if(this.props.data){
var projects = this.props.data.projects.map((projects) => {
var projectImage = 'images/portfolio/'+projects.image;
return <div key={projects.title} className="columns portfolio-item">
<div className="item-wrap">
<a onClick={() => this.toggleModal(projects,projectImage)} className="open-popup" title={projects.title}>
<img alt={projects.title} src={projectImage} />
<div className="overlay">
<div className="portfolio-item-meta">
<h5>{projects.title}</h5>
<p>{projects.category}</p>
</div>
</div>
<div className="link-icon"><i className="fa fa-link"></i></div>
</a>
</div>
</div>
})
}
return (
<section id="portfolio">
<div className="row">
<div className="twelve columns collapsed">
<h1>Check Out Some of My Works.</h1>
<div id="portfolio-wrapper" className="bgrid-quarters s-bgrid-thirds cf">
{projects}
<Modal show={this.state.isOpen} onClose={this.toggleModal} >
<img alt={this.state.activeProjects.title} src={this.state.activeProjectImage} />
</Modal>
</div>
</div>
</div>
</section>
);
}
}
export default Portfolio;

Your render method should have return statement?

class App extends React.Component {
render() {
productList.map((product) => {
return (
<div className="mainContainer">
<div className="titel">{product.title}</div>
<div className="type">{product.type}</div>
<div className="producer">{product.producer}</div>
<div className="unit">{product.unit}</div>
<div className="prisContainer">
<div className="pris">{product.price}</div>
</div>
</div>
);
});
}
}
export default App;
What am I doing wrong?
As the error states, you aren't returning anything from within the render function. Returning the mapped result will solve the problem if you are on v16 or above of react.
class App extends React.Component {
render() {
return productList.map((product) => {
return (
<div className="mainContainer">
<div className="titel">{product.title}</div>
<div className="type">{product.type}</div>
<div className="producer">{product.producer}</div>
<div className="unit">{product.unit}</div>
<div className="prisContainer">
<div className="pris">{product.price}</div>
</div>
</div>
);
});
}
}
export default App;
If you are on a lower version, wrap the result of map function within a div
render() {
return <div>{productList.map((product) => {
return (
<div className="mainContainer">
<div className="titel">{product.title}</div>
<div className="type">{product.type}</div>
<div className="producer">{product.producer}</div>
<div className="unit">{product.unit}</div>
<div className="prisContainer">
<div className="pris">{product.price}</div>
</div>
</div>
);
})}<div>
}
I would create a seperate variable that runs the map and returns the content and then add the variable in the return statement within the render
render() {
return (
<div> {content} </div>
)
}

Second Component cannot reload data

Hi i have problem using reactjs to reload the second component in parent component.
I have some 3 file 1 parent component 2 child component to make simple chat website.
The problem is my component Chatroom was not reload/change the data when i click the Chatlist in the second time.
This is my parent.js
import React, { useContext } from 'react'
import $ from 'jquery'
import Wrapper from '../components/wrapper'
import ChatList from './chat-list'
import ChatRoom from './chat-room'
export default class extends React.Component {
constructor(props) {
super(props)
this.state = {
login: 0,
user: null,
tokenChat: '',
roomChat: '',
isToken: false
}
this.clickChat = this.clickChat.bind(this)
}
componentDidMount() {
$('body').addClass('menu-position-side menu-side-left')
}
componentWillUnmount() {
$('body').removeClass('menu-position-side menu-side-left')
}
clickChat(token, room) {
let self = this
self.setState({
tokenChat: token,
roomChat: room,
isToken: true
})
}
render() {
return (
<Wrapper {...this.props} title="Dashboard" selected="dashboard" padding={false}>
{this.state.login == 1 &&
<div className="content-i">
<div className="content-box">
<div className="full-chat-w">
<div className="full-chat-i">
<div className="full-chat-left">
<div className="os-tabs-w">
<ul className="nav nav-tabs upper centered">
...
</ul>
</div>
<ChatList clickChat={this.clickChat} />
</div>
<div className="full-chat-middle">
{
this.state.isToken == false ?
null
:
<ChatRoom token={this.state.tokenChat} room={this.state.roomChat} />
}
</div>
<div className="full-chat-right">
<div className="user-intro">
<div className="avatar"><img alt="" src="/static/doctor-theme/img/avatar1.jpg" /></div>
<div className="user-intro-info">
<h5 className="user-name">John Mayers</h5>
<div className="user-sub">San Francisco, CA</div>
<div className="user-social"><i className="os-icon os-icon-twitter"></i><i className="os-icon os-icon-facebook"></i></div>
</div>
</div>
<div className="chat-info-section">
<div className="ci-header"><i className="os-icon os-icon-documents-03"></i><span>Shared Files</span></div>
<div className="ci-content">
<div className="ci-file-list">
<ul>
<li>Annual Revenue.pdf</li>
<li>Expenses.xls</li>
<li>Business Plan.doc</li>
</ul>
</div>
</div>
</div>
<div className="chat-info-section">
<div className="ci-header"><i className="os-icon os-icon-documents-07"></i><span>Shared Photos</span></div>
<div className="ci-content">
<div className="ci-photos-list">
<img alt="" src="/static/doctor-theme/img/portfolio9.jpg" />
<img alt="" src="/static/doctor-theme/img/portfolio2.jpg" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
</Wrapper>
)
}
}
Please Help Thank you.

Dynamically expand/collapse on click of header

I have a set of items that needs to be shown in the UI, like a header and list of items under it. There is a parent component where I am passing this data to a file that is shown below. Based on this the parent-child layout is shown. Now I need to expand/collapse based on the click of the header.
There is a class "open" and "close " that can be attached to the div. Based on it the it gets collapse/expands. The point is how do it item wise
Can someone help
import React from "react";
import Child from "./Child";
import Parent from "./Parent";
export default class Helper extends React.Component{
constructor(props: any) {
super(props);
this.state = {
parent:{},
children:{},
};
}
componentDidMount() {
this.setParentValue();
this.setChildValue();
}
render() {
const { parent, children } = this.state;
const { name } = this.props;
return (
<>
<div className="an-panel expand-panel expand-close">
<div className="an-panel-header">
<div className="title-holder">
<span className="toggle-icon far fa-plus-square" />
<span className="toggle-icon far fa-minus-square" />
<h5>{name}</h5>
</div>
<div className="action-holder">
<div className="status-holder">
<Parent
parent = {parent}
onSelect={this.handleParentClick}
/>
</div>
</div>
</div>
{children.map(({ id, name },id) => (
<div className="an-panel-body" key={id}>
<ul className="applications-list-holder">
<li>
<div className="name">{name}</div>
<div className="status">
<Child
children={children}
onSelect={this.setChildSwitchValue}
/>
</div>
</li>
</ul>
</div>
))}
</div>
</>
);
}
}
Ok let me explain it to you, here is your code
import React from "react";
import Child from "./Child";
import Parent from "./Parent";
export default class Helper extends React.Component{
constructor(props: any) {
super(props);
this.state = {
parent:{},
children:{},
navBarStatus: false,
};
}
componentDidMount() {
this.setParentValue();
this.setChildValue();
}
changeNavBar = (e, status)=>{
this.setState({navBarStatus: !status});
}
render() {
const { parent, children } = this.state;
const { name } = this.props;
return (
<>
<div className={`an-panel expand-panel ${this.state.navBarStatus ? "expand-open" : "expand-close"}`}>
<div className="an-panel-header" onClick={(e)=>this.changeNavBar(e, this.state.navBarStatus)}>
<div className="title-holder">
<span className="toggle-icon far fa-plus-square" />
<span className="toggle-icon far fa-minus-square" />
<h5>{name}</h5>
</div>
<div className="action-holder">
<div className="status-holder">
<Parent
parent = {parent}
onSelect={this.handleParentClick}
/>
</div>
</div>
</div>
{children.map(({ id, name },id) => (
<div className="an-panel-body" key={id}>
<ul className="applications-list-holder">
<li>
<div className="name">{name}</div>
<div className="status">
<ChildSetting
children={children}
onSelect={this.setChildSwitchValue}
/>
</div>
</li>
</ul>
</div>
))}
</div>
</>
);
}
}
You can see I have taken a new property in state navBarStatus. Based on navBarStatus value I am changing CSS class which will expand/close your attached div

How can I display array of data in specific div id by click in a button?

I create a component of react. and there one array with some values. so I need to display that value or data in any specific div by clicking in a button.
this is my array in component.
constructor(){
super()
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5",
]
}
}
this is my button with click event.
<button onClick={this.getNotification}>{this.state.notificaion.length}</button>
this is the function that I have create. and to push data in specific div.
getNotification = () =>{
return(
this.state.notificaion.map(items =>(
<li key={items}>{items}</li>
))
)
}
here I want to display when buttons is clicked
<strong>{this.getNotification()}</strong>
This is my full code that I have been tried.
import React, {Component} from 'react';
class Menu2 extends Component{
constructor(){
super()
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5",
]
}
}
getNotification = () =>{
return(
this.state.notificaion.map(items =>(
<li key={items}>{items}</li>
))
)
}
render(){
return(
<div className="header">
<div className="container">
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="text-center mb-20">
<h1>Notificaion Status</h1>
<p>Check notificatin read/unread</p>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="card border-dark mb-3">
<div className="card-body text-dark">
<p className="card-text" style={{textAlign: 'center'}}>
{this.state.notificaion.length > 0
?
<span>You Have <button onClick={this.getNotification}>{this.state.notificaion.length}</button> Unread Notifications</span>
:
<span>You Have <button onClick={this.getNotification}>{this.state.notificaion.length}</button> Unread Notifications}</span>}
</p>
<strong>{this.getNotification()}</strong>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Menu2;
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5",
],
notificationHtml: ""
}
}
getNotification = () => {
this.setState({
notificationHtml: this.state.notificaion.map(items => (
<li key={items}>{items}</li>
))
});
}
render() {
return (
<div className="App">
<button onClick={this.getNotification}>{this.state.notificaion.length}</button>
<div>
{this.state.notificationHtml}
</div>
</div>
);
}
}
export default App;
I would implemented as such:
this.state = {
visible: false,
notifications: ...
}
toggleVisibility() =>{
this.setState({
visibile: true
})
}
Don't forget to bind the "toggleVisibility" function. Then
in your component:
<button onClick={this.toggleVisibility}/>
...
{if(this.state.visible){
<strong>this.state.notifications.map(notification,i) =>
<li key={i}>{notification}</li>
</strong>
}
You can add a property showNotification in state. And based on the value of it, we can show the notification.
Also add a method showNotificationHandler that toggles the showNotification value.
class Menu2 extends Component {
constructor() {
super();
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5"
],
// adding a property "showNotification"
showNotification: false
};
}
getNotification = () => {
return this.state.notificaion.map(items => <li key={items}>{items}</li>);
};
// method that toggles the "showNotification" value
showNotificationHandler = () => {
this.setState(({ showNotification }) => ({
showNotification: !showNotification
}));
};
render() {
return (
<div className="header">
<div className="container">
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="text-center mb-20">
<h1>Notificaion Status</h1>
<p>Check notificatin read/unread</p>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="card border-dark mb-3">
<div className="card-body text-dark">
<p className="card-text" style={{ textAlign: "center" }}>
{this.state.notificaion.length > 0 ? (
<span>
You Have{" "}
<button onClick={this.showNotificationHandler}>
{this.state.notificaion.length}
</button>{" "}
Unread Notifications
</span>
) : (
<span>
You Have{" "}
<button onClick={this.showNotificationHandler}>
{this.state.notificaion.length}
</button>{" "}
Unread Notifications}
</span>
)}
</p>
<strong>
// Depending on the value of "showNotification" we get notification
// if "showNotification" is true then get the notification
{this.state.showNotification && this.getNotification()}
</strong>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Menu2;

Categories

Resources