Using Reactjs to align and display results based on Contestant ID - reactjs

The code below displays three Election Contestants from the arrays.
Now I want to show their vote counts for each contestanst based on their Ids.
here is the arrays showing various contestant results that i want to merge based on their Id's
contestantResult: [
{ id: 1, voteCount: "500 Votes" },
{ id: 2, voteCount: "200 Votes" },
{ id: 3, voteCount: "320 votes" },
],
My issues is stated below:
Each time I run the code, all the three contestant are seen having 500 votes but in reality based on their Ids,
Contestant 1 should have 500 votes.
Contestant 2 should have 200 votes.
Contestant 3 should have 320 votes.
I guess I have to loop through the contestant Vote results arrays using something like map() functions as per the code below but do not know
how to apply it. Any help or solutions will be appreciated
{this.state.contestantResult.map((contestant, i) => {
//if (contestant.id == person.id) {
if (contestant.id) {
return (
<div key={i}>
<div>{contestant.voteCount}</div>
</div>
);
}
})}
Below is my coding efforts so far
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
class Contestant extends React.Component {
constructor() {
super();
this.state = {};
}
render() {
return (
<React.Fragment>
<div key={this.props.data.id}>
<div style={{ background: "black", color: "white" }}>
<b>Id:</b>
{this.props.data.id}
<br />
<b>Name:</b> {this.props.data.name}
<br />
<b style={{ color: "red" }}>Vote Count: {this.props.resultVotes}</b>
<br />
</div>
</div>
</React.Fragment>
);
}
}
class VoteResult extends React.Component {
constructor() {
super();
this.state = {
data: [
{ id: 1, name: "contestant 1" },
{ id: 2, name: "contestant 2" },
{ id: 3, name: "contestant 3" }
],
contestantResult: [
{ id: 1, voteCount: "500 Votes" },
{ id: 2, voteCount: "200 Votes" },
{ id: 3, voteCount: "320 votes" }
]
};
}
componentDidMount() {}
render() {
return (
<div>
<h1> Electoral College Voting......</h1>
{this.state.data.map(person => {
return (
<Contestant
key={person.id}
data={person}
resultVotes={this.state.contestantResult[0].voteCount}
/>
);
})}
</div>
);
}
}

You don't want to take the first object in the contestantResult array for every iteration in the loop. You could instead use find to find the result of the correct contestant.
{this.state.data.map(person => {
const result = this.state.contestantResult.find(res => res.id === person.id);
return (
<Contestant
key={person.id}
data={person}
resultVotes={result.voteCount}
/>
);
})}
class VoteResult extends React.Component {
state = {
data: [
{ id: 1, name: "contestant 1" },
{ id: 2, name: "contestant 2" },
{ id: 3, name: "contestant 3" }
],
contestantResult: [
{ id: 1, voteCount: "500 Votes" },
{ id: 2, voteCount: "200 Votes" },
{ id: 3, voteCount: "320 votes" }
]
};
render() {
const { data, contestantResult } = this.state;
return (
<div>
<h1> Electoral College Voting......</h1>
{data.map(person => {
const result = contestantResult.find(res => res.id === person.id);
return (
<Contestant
key={person.id}
data={person}
resultVotes={result.voteCount}
/>
);
})}
</div>
);
}
}
class Contestant extends React.Component {
render() {
return (
<div key={this.props.data.id}>
<div style={{ background: "black", color: "white" }}>
<b>Id:</b>
{this.props.data.id}
<br />
<b>Name:</b> {this.props.data.name}
<br />
<b style={{ color: "red" }}>Vote Count: {this.props.resultVotes}</b>
<br />
</div>
</div>
);
}
}
ReactDOM.render(<VoteResult />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Related

Props is not updating in class component React

I am Traying to pass props as product data object on clicking on that product in class component in react but element values are not getting assigned the following code for which am trying for plz help to solve this problem I am new at class component in react
class ProductList extends React.Component {
constructor() {
super()
this.state = {
product:undefined,
productsList: [
{
id: 1,
name: 'Samsung Galaxy Note 10',
category: 'Mobiles',
country: 'Canada',
price: 11500,
currencyCode: 'CAD',
productImage: require('./assets/img/product1.jpg'),
},
{
id: 5,
name: 'SkullCandy BT Inkd Plus',
category: 'Bluetooth Headset',
country: 'UK',
price: 800,
currencyCode: 'USD',
productImage: require('./assets/img/product2.jpg'),
}
],
}
}
render() {
return (
<>
<div className="ProductList">
<ul id="products" className="products">
{this.state.productsList.map((element, i) => (
<li
id={'product' + i}
onClick={() => this.setState({ product: 'abc' })}
>
<img id={'image' + i} src={element.productImage} />
<b>{element.name}</b>
</li>
))}
</ul>
</div>
<div className="productComponent">
{console.log(this.product)}
<Product productProp={this.product} />
</div>
</>
)
}
}
export default ProductList
Pass props as this.state.product instead of this.product
<Product productProp={this.state.product} />

how to add onClick function to array

I am trying to add onClick function to this array. So when i click on "How will i get cashback?",output
it must display the items(Page Page One,Two) image and when i click on "Page Page One", it must display "Subcontent"
stackblitz
export default class Chat extends React.Component {
constructor(props) {
super(props);
this.state = {
message: [
{
id: 1,
title: "How will i get cashback?",
items: [
{
id: 1,
title: "Page Page One",
items: [
{
id: 1,
title: 'SubContent'
}
],
},
{
id: 2,
title: "Two",
},
],
},
{
id: 2,
title: "Reschedule delivery",
items: [],
},
],
};
}
render() {
const { message } = this.state;
return (
<div>
<p className={styles.titleText}>AAAAAA</p>
<div className={styles.line} />
{message.map((m) => (
<div>
<div
className={styles.button}
>
{m.title}
<i
className={`fa fa-chevron-right`}
aria-hidden="true"
/>
</div>
<div className={styles.line} />
</div>
))}
</div>
);
}
}
Add this change to your code.
Basically what you are telling your program is "If I have items, then set the state to be these items, else do nothing"
<div className={`button`} onClick={() => m.items ? this.setState({ message: m.items }) : null}>
{m.title}
<i className={`fa fa-chevron-right`} aria-hidden="true" />
</div>

State in react is not rendering/displaying to the screen

I'm not able get what I'm doing wrong here. Could someone please help me out here. I'm unable to print the value to the screen. I'm trying to print the value from the state to the screen but I'm unable to.
Its not showing any error. I know this could be a silly mistake. Please help me out. Thanks
I'm not able get what I'm doing wrong here. Could someone please help me out here. I'm unable to print the value to the screen. i'm trying to print the value from the state to the screen but i'm unable to.
Its not showing any error.
import React, { Component } from "react";
import "./Screen.css";
export default class Screen extends Component {
constructor(props) {
super(props);
this.state = {
roles: [
{ id: 1, value: "Contracts manager", isChecked: false },
{ id: 2, value: "In-house counsel", isChecked: false },
{ id: 3, value: "IT administrator", isChecked: false },
{ id: 4, value: "Law clerk", isChecked: false },
{ id: 5, value: "Legal administrator", isChecked: false },
{ id: 6, value: "Legal operations manager", isChecked: false },
{ id: 7, value: "Legal secretary", isChecked: false },
{ id: 8, value: "Paralegal", isChecked: false },
{ id: 9, value: "Procurement manager", isChecked: false },
{ id: 10, value: "Solicitor", isChecked: false },
{ id: 11, value: "Other", isChecked: false },
],
aksha: "aksk",
};
console.log(this.state);
}
roleHandler = (event) => {
let roles = this.state.roles;
roles.forEach((role) => {
if (role.value === event.target.value)
role.isChecked = event.target.checked;
});
this.setState({ roles: roles });
};
render() {
const newRoles = this.state.roles.map((role) => {
return (
<div className="border-inp">
<label className="checkbox">
<span className="checkbox__input">
<input
type="checkbox"
name="checkbox"
key={this.state.roles.id}
onClick={this.roleHandler}
value={this.state.roles.value}
checked={this.state.roles.checked}
/>{" "}
{this.state.roles.value}
</span>
</label>
</div>
);
});
return (
<div>
<div className="Screenbg">
<div id="viewport" className="screenview">
<h3 className="wel">Welcome</h3>
<div>
<h5 className="role">What is your role?</h5>
{newRoles}
</div>
<div className="grid-container btndiv">
{/* <div className="grid-child purple">
<button className="btn">Back</button>
</div> */}
<div className="grid-child green">
{/* <Link to="/"> */}
<button className="btn">Next</button>
{/* </Link> */}
</div>
</div>
</div>
</div>
</div>
);
}
}
role must be used for rendering your array. You were using state to get it.
render() {
const newRoles = this.state.roles.map((role) => {
return (
<div className="border-inp">
<label className="checkbox">
<span className="checkbox__input">
<input
type="checkbox"
name="checkbox"
key={this.state.roles.id}
onClick={this.roleHandler}
value={this.state.roles.value}
checked={this.state.roles.checked}
/>
{role.value}
</span>
</label>
</div>

Mapping of images to get particular data image on hover

Code below is an example of creation by me in code sandbox. I map sum of images and try to hover image and get that image details...if I hover on one image its getting all images data.
Can anyone help on this: https://codesandbox.io/s/romantic-haslett-qreg1?file=/src/App.js:0-1096
import React, { Component } from "react";
import "./styles.css";
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ text: "sun", image: require("./images/sun.webp") },
{ text: "sky", image: require("./images/sky.jpg") },
{ text: "tree", image: require("./images/tree.jpg") }
],
hover: false
};
}
Hover = () => {
this.setState({
hover: true
});
};
NotHover = () => {
this.setState({
hover: false
});
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div>
<img
className="image"
onMouseEnter={this.Hover}
onMouseLeave={this.NotHover}
src={image.image}
alt=""
/>
{this.state.hover &&
<div>
<li>{image.text}</li>
</div>}
</div>
))}
</div>
);
}
}
You could save a state for hover status of each image by its key
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ text: "sun", image: require("./images/sun.webp") },
{ text: "sky", image: require("./images/sky.jpg") },
{ text: "tree", image: require("./images/tree.jpg") }
],
hover: {
0: false,
1: false,
2: false
}
};
}
AddressMenuBox = (key) => () => {
this.setState({
hover: { [key]: true }
});
};
AddressMenuBoxLeave = (key) => () => {
this.setState({
hover: { [key]: false }
});
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div>
<img
className="image"
onMouseEnter={this.AddressMenuBox(key)}
onMouseLeave={this.AddressMenuBoxLeave(key)}
src={image.image}
alt=""
/>
{this.state.hover[key] && (
<div>
<li>{image.text}</li>
</div>
)}
</div>
))}
</div>
);
}
}
Codesandbox for implementation
You have to differentiate between the elements to force hover only on selected image, therefore you could provide additional id property to your images and change hover state to hoverTargetId so that it represents an id of selected item.
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ id: 0, text: "sun", image: require("./images/sun.webp") },
{ id: 1, text: "sky", image: require("./images/sky.jpg") },
{ id: 2, text: "tree", image: require("./images/tree.jpg") }
],
hoverTargetId: null
};
}
onHoverStart = targetId => () => {
this.setState({ hover: targetId });
};
onHoverEnd = () => {
this.setState({ hover: null });
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div key={key}>
<img
className="image"
onMouseEnter={this.onHoverStart(image.id)}
onMouseLeave={this.onHoverEnd}
src={image.image}
alt=""
/>
{this.state.hover === image.id &&
<div>
<li>{image.text}</li>
</div>
}
</div>
))}
</div>
);
}
}
The id i've introduced could be substituted by your iteration index (key), but it's a better practice to not handle such things based on dynamically generated values.
Change your code with the boolean variable to show target image:
import React, { Component } from "react";
import "./styles.css";
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ text: "sun", image: require("./images/sun.webp"), show: false },
{ text: "sky", image: require("./images/sky.jpg"), show: false },
{ text: "tree", image: require("./images/tree.jpg"), show: false }
],
hover: false
};
}
AddressMenuBox = (key) => {
let items = [...this.state.Images];
let item = { ...items[key] };
item.show = true;
items[key] = item;
this.setState({
hover: true,
Images: items
});
};
AddressMenuBoxLeave = (key) => {
let items = [...this.state.Images];
let item = { ...items[key] };
item.show = false;
items[key] = item;
this.setState({
hover: false,
Images: items
});
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div>
<img
className="image"
onMouseEnter={() => this.AddressMenuBox(key)}
onMouseLeave={() => this.AddressMenuBoxLeave(key)}
src={image.image}
alt=""
/>
{this.state.hover && image.show && (
<div>
<li>{image.text}</li>
</div>
)}
</div>
))}
</div>
);
}
}
Edit code on sanbox:
https://codesandbox.io/s/distracted-gagarin-54zv4?file=/src/App.js:0-1462

How to display nested array data in JSON in ReactJS?

I have problem to display nested array data that I retrieved from api call. The JSON data format is like:
[
{
pageNo: 1
TotalRecordsCount: 8000,
Items: [
{
id: 1,
subject: "ACCOUNTING",
campus: "campus A"
},
{
id: 1,
subject: "ACCOUNTING",
campus: "campus A"
},
...
}
]
Edit data format:
Items: [{subject: ACCOUNTING, CAMPUS: CAMPUS A}, {subject: ACCOUNTING, campus: CAMPUS A}...]
PageNo: 1
TotalRecordCount: 8000
in JSON format.
How to access subject, campus, etc. data in ReactJS? I got the error message: Objects are not valid as a React child (found: object with keys {courseItem}).
App.js
import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {
constructor() {
super();
this.state ={
courses:[]
};
}
componentDidMount(){
axios.get('myURL')
.then(response=>{
this.setState({
courses:response.data
});
});
}
_getCourses(){
const data=this.state.courses;
const courseItem=data.map((course,index)=>(
<div>
Page No: course.ageNo <br />
<div className="courseItem"><ul>
Course: <li>ID:{course.id}
SUBJECT:{course.subject}
CAMPUS: {course.campus} </li>
</ul></div>
</div>
));
render() {
const courses= this._getCourses();
return (
<div className="App">
<div className="courseResults">
{courses}
</div>
</div>
);
}
}
export default App;
Thanks.
In componentDidMount you are currently setting courses to just response.data. And this is the outer array from your response. The courses array is the inner array. So, you need to set courses to response.data[0].Items. Perhaps you want to iterate over response.data array as well if you expect more than one entry there.
componentDidMount() {
axios.get('http://localhost:8080')
.then(response => {
this.setState({
courses: response.data[0].Items
});
});
}
In _getCourses you need to return the courseItems variable:
_getCourses() {
const data = this.state.courses;
const courseItems = data.map((course, index) => (
<div>
Page No: course.ageNo <br />
<div className="courseItem"><ul>
Course: <li>ID:{course.id}
SUBJECT:{course.subject}
CAMPUS: {course.campus} </li>
</ul></div>
</div>
));
return courseItems;
}
You have the render function inside of the _getCourses and it has to be on the same level, at the class level:
class App extends Component {
constructor() { ... }
componentDidMount() { ... }
_getCourses() { ... }
render() { ... }
}
import React, { Component } from 'react';
import { render } from 'react-dom';
class App extends Component {
constructor() {
super();
this.state = {
courses: [
{
pageNo: 1,
TotalRecordsCount: 8000,
Items: [
{
id: 1,
subject: "ACCOUNTING",
campus: "campus A"
},
{
id: 1,
subject: "ACCOUNTING",
campus: "campus A"
}
]
}
]
}
}
_getCourses() {
const data = this.state.courses.slice(0);
const courseItem = data.map((course, index) => (
<div>
Page No: course.ageNo <br />
<div className="courseItem">
<ul>
{course.Items.map((details, index) => (
<React.Fragment>
<li>
Course: ID:{details.id}
</li>
<li>
SUBJECT:{details.subject}
</li>
<li>
CAMPUS: {details.campus}
</li>
</React.Fragment>))}
</ul>
</div>
</div>
))
return courseItem;
}
render() {
return (
<div className="App">
<div className="courseResults">
{this._getCourses()}
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));
https://stackblitz.com/edit/react-mnh5ex?embed=1&file=index.js
You needed to return courseItem in the _getCourse function. Otherwise it will not render any html when you call the _getCourse in the render function.
You also need to acess Items, because Items contains the data you want to access.
{
id: 1,
subject: "ACCOUNTING",
campus: "campus A"
},
{
id: 1,
subject: "ACCOUNTING",
campus: "campus A"
}

Resources