I'm trying to have a nested map but i'm getting an undefined error.
So i'm passing the profile props to Link router in navbar.jsx, profile: this.state.profile. Then I fetching the data in profilePage.jsx, where I want to pass the data in an element.
Profile json has 3 components -> experience, education, and skills. So i need to have a nested loop for the data to show up in the element. For example; calling `{experience.company} so the company name will show up.
When i called the profile page, in the console i see profile.experience getting called but then it goes undefined:
(3) [{...}, {...}, {...}] "passing"
undefined "passing"
I tried different ways, splitting the json components but still getting the same error. I know it's mapping issue but I'm not sure if I'm missing something, maybe in React; new to React so learning as much as I can through errors. Your help will be appreciated!
Eventually I want the profile page to look like this:
Education
Company A
August 2016 - present
salesman
Company B
Feb 2016 - August 2016
developer
Company C
August 2012 - October 2015
clerk
Education
school A
fall 2015
mathematics
school B
may 2008
business
Skills
tools: html, css, js, sql
profilePage.jsx
import React, { Component } from "react";
import ProfileItem from "./profileItem"
class Profile extends Component {
render(){
// let profile = this.props.location.profile.map((experience) => <li>{experience.experience}</li>);
// console.log(profile);
const experience = this.props.location.profile.map((profile,idx) => {
console.log(profile.experience, 'passing');
return profile.experience.map((experience,idx) =>
<div>
<p key={idx}>{experience.company}</p>
</div>
);
});
}
}
export default Profile;
navbar.jsx
import React, { Component } from "react";
import { Link } from "react-router-dom";
class Navbar extends Component {
constructor(props){
super(props);
this.state = {
profile: [
{'experience': [
{
'company': 'company A',
'date': 'August 2016 - Present',
'jobTitle': 'salesman'
},
{
'company': 'company B',
'date': 'February 2016 - August 2016',
'jobTitle': 'Developer'
},
{
'company': 'company C',
'date': 'August 2012 - October 2015',
'jobTitle': 'clerk'
}
]},
{'education': [
{
'school': 'shcool A',
'date': 'Fall 2015',
'degree': 'mathematics'
},
{
'school': 'school B',
'date': 'May 2008',
'degree': 'business'
}
]},
{'skills': [
{
'Tools': 'HTML, CSS, Javascript, SQL, Python'
}
]}
],
experience: [],
education: [],
skills: []
};
}
render(){
return (
<div className="navFrame">
<Link to="/">
<div className="topNav"><div className="navBar"><h3>name</h3></div></div>
</Link>
<Link to="/projects">
<div className="rightNav"><div className="navBar"><h3>Projects</h3></div></div>
</Link>
<Link to="/contact">
<div className="bottomNav"><div className="navBar"><h3>Contact</h3></div></div>
</Link>
<Link to={{pathname: '/profile', profile: this.state.profile}}>
<div className="leftNav"><div className="navBar"><h3>Profile</h3></div></div>
</Link>
</div>
);
}
}
export default Navbar;
Try to run this on browser's console =>
From your given Json:
var response = {profile: [
{'experience': [
{
'company': 'company A',
'date': 'August 2016 - Present',
'jobTitle': 'salesman'
},
{
'company': 'company B',
'date': 'February 2016 - August 2016',
'jobTitle': 'Developer'
},
{
'company': 'company C',
'date': 'August 2012 - October 2015',
'jobTitle': 'clerk'
}
]},
{'education': [
{
'school': 'shcool A',
'date': 'Fall 2015',
'degree': 'mathematics'
},
{
'school': 'school B',
'date': 'May 2008',
'degree': 'business'
}
]},
{'skills': [
{
'Tools': 'HTML, CSS, Javascript, SQL, Python'
}
]}
],
experience: [],
education: [],
skills: []
}
when we try to run response.profile.map() it will iterate over all the elements present in this array
response.profile.map(ele => console.log(ele)) will give 3 elements i.e. experience, education and skills
now within an inner block of your code when you will iterate over this element for the first time you will get experience key as defined but for next two iterations it will fail since the key is not present. you can add a filter in between the way I've done below !
const experience = this.props.location.profile
.filter(profile => profile.hasOwnProperty("experience"))
.map((profile, idx) => {
return profile.experience.map((experience, idx) => (
<div>
<p key={idx}>{experience.company}</p>
</div>
));
});
Hope this might help !
Related
I'm creating an interactive viz with React and I would like to add a slider in my viz.
import "./styles.css";
import React from "react";
import Sunburst from "react-zoomable-sunburst";
import { data } from "./data";
import { Slider } from "#mui/material";
class App extends React.Component {
onSelect(event) {
console.log(event);
}
render() {
return (
<div className="App">
<Sunburst
width="400"
height="400"
data={data.a}
count_member="size"
labelFunc={(node) => node.data.name}
_debug={false}
/>
<Slider
aria-label="Year"
defaultValue={2016}
valueLabelDisplay="auto"
step={1}
marks
min={2016}
max={2020}
/>
</div>
);
}
}
export default App;
Above is my code. I added my data from 2016 to 2020 in data.js file and I want my viz to change according to the year as I move my slider.
a: {
name: "2020",
children: [
{
name: "Campus",
children: [
{
name: "Liabilities",
children: [
{
name: "Current Liabilities",
children: [
{ name: "Accounts payable", size: 53010 },
{ name: "Accrued salaries", size: 23554 },
{ name: "Unearned revenue", size: 253322 },
{ name: "Commercial paper", size: 326008 },
{ name: "Current portion of long-term debt", size: 112431 },
{ name: "Funds held for others", size: 2500 },
{ name: "Other current liabilities", size: 71036 }
]
}
This is a part of my code in data.js and I named 2016 data as a, 2017 as b, and so on.
I wanted to name as 2016, 2017... instead of a,b... but this didn't work since data.2016 didn't work. (So I made it data.a in the code above)
So currently, my slider doesn't work. Is there any way to make dictionary or other method in React to resolve this problem?
Thanks.
use
data['2016']
That should work.
I am new to react js. I am trying to use the map function on an array that is stored in another file called products.js , when I console log the data it is showing by not showing in the screen. This is my code for the component:
import React from 'react'
import products from '../products'
import {Row,Col} from 'react-bootstrap'
const HomeScreen = () => {
console.log(products)
return (
<>
<h1>Latest Products</h1>
<Row>
{products.map(product => {
<h3 key={product._id}>{product.name}</h3>
})}
</Row>
</>
)
}
export default HomeScreen
This is the product.js code:
const products = [
{
_id: '1',
name: 'Airpods Wireless Bluetooth Headphones',
image: '/images/airpods.jpg',
description:
'Bluetooth technology lets you connect it with compatible devices wirelessly High-quality AAC audio offers immersive listening experience Built-in microphone allows you to take calls while working',
brand: 'Apple',
category: 'Electronics',
price: 89.99,
countInStock: 10,
rating: 4.5,
numReviews: 12,
},
{
_id: '2',
name: 'iPhone 11 Pro 256GB Memory',
image: '/images/phone.jpg',
description:
'Introducing the iPhone 11 Pro. A transformative triple-camera system that adds tons of capability without complexity. An unprecedented leap in battery life',
brand: 'Apple',
category: 'Electronics',
price: 599.99,
countInStock: 7,
rating: 4.0,
numReviews: 8,
},
{
_id: '3',
name: 'Cannon EOS 80D DSLR Camera',
image: '/images/camera.jpg',
description:
'Characterized by versatile imaging specs, the Canon EOS 80D further clarifies itself using a pair of robust focusing systems and an intuitive design',
brand: 'Cannon',
category: 'Electronics',
price: 929.99,
countInStock: 5,
rating: 3,
numReviews: 12,
},
{
_id: '4',
name: 'Sony Playstation 4 Pro White Version',
image: '/images/playstation.jpg',
description:
'The ultimate home entertainment center starts with PlayStation. Whether you are into gaming, HD movies, television, music',
brand: 'Sony',
category: 'Electronics',
price: 399.99,
countInStock: 11,
rating: 5,
numReviews: 12,
},
{
_id: '5',
name: 'Logitech G-Series Gaming Mouse',
image: '/images/mouse.jpg',
description:
'Get a better handle on your games with this Logitech LIGHTSYNC gaming mouse. The six programmable buttons allow customization for a smooth playing experience',
brand: 'Logitech',
category: 'Electronics',
price: 49.99,
countInStock: 7,
rating: 3.5,
numReviews: 10,
},
{
_id: '6',
name: 'Amazon Echo Dot 3rd Generation',
image: '/images/alexa.jpg',
description:
'Meet Echo Dot - Our most popular smart speaker with a fabric design. It is our most compact smart speaker that fits perfectly into small space',
brand: 'Amazon',
category: 'Electronics',
price: 29.99,
countInStock: 0,
rating: 4,
numReviews: 12,
},
]
export default products
And this is my App.js code :
import React from 'react'
import {Container} from 'react-bootstrap'
import Header from './components/Header'
import Footer from './components/Footer'
import HomeScreen from './screens/HomeScreen'
const App=()=> {
return (
<>
<Header />
<main>
<Container className='py-3'>
<HomeScreen/>
</Container>
</main>
<Footer/>
</>
);
}
export default App;
Why is this happening? I have tried looking up some solutions but failed. Thank you for helping
Add a return statement in the map function.
{products.map((product) => {
return <h3 key={product._id}>{product.name}</h3>;
})}
I think the problem is that you need to add a return statement before the h3:
<Row>
{products.map(product => {
return <h3 key={product._id}>{product.name}</h3>
})}
</Row>
If you want to do it this way without using 'return', there are 2 options:
Option 1: Remove the curly braces
<Row>
{products.map(product => return <h3 key={product._id}>{product.name}</h3>)}
</Row>
Option 2: Use () instead of the curly braces (Most especially when you are gonna add more elements later)
<Row>
{products.map(product => (
<h3 key={product._id}>{product.name}</h3>
<...other html elements>
))}
</Row>
Whenever I run my React program, I receive the following error:
Objects are not valid as a React child (found: object with keys {mappedCats}). If you meant to render a collection of children, use an array instead.
in choicesList (at App.js:33)
What I am trying to do is take the FEATURES object, iterate through it and create a div for each category. Then iterate through the items of that category to show the name and cost of each item. I tried converting the object to an array, but it doesn't seem to be working. Originally I tried splitting this up into multiple components but I think I was overly ambitious.
The Categories component just takes the props and puts them into a div and paragraphs.
If somebody could point out my mistake I would appreciate it. Thank You
import React from 'react'
import Categories from './categories'
const choicesList = (props) => {
const FEATURES = {
Processor: [
{
name: '17th Generation Intel Core HB (7 Core with donut spare)',
cost: 700
},
{
name: 'Professor X AMD Fire Breather with sidewinder technology',
cost: 1200
}
],
"Operating System": [
{
name: 'Ubuntu Linux 16.04',
cost: 200
},
{
name: 'Bodhi Linux',
cost: 300
}
],
"Video Card": [
{
name: 'Toyota Corolla 1.5v',
cost: 1150.98
},
{
name: 'Mind mild breeze 2000',
cost: 1345
}
],
Display: [
{
name: '15.6" UHD (3840 x 2160) 60Hz Bright Lights and Knobs',
cost: 1500
},
{
name: '15.3" HGTV (3840 x 2160) Home makeover edition',
cost: 1400
},
]
};
const mappedCats = Object.keys(FEATURES).map((cat) => {
return (
<div>
<h1>{cat}</h1>
{Object.keys(FEATURES[cat]).map((item, idx) => {
return (
<Categories name={FEATURES[cat][idx].name} cost={FEATURES[cat][idx].cost}/>
)
})}
</div>
)
})
return(
{mappedCats}
)
}
export default choicesList
Because React components must render a single root element, you'd need to wrap it in either a fragment or an element:
return (
<>{ mappedCats }</>
)
As raw js (not enclosed in markup) your render method is returning an object literal:
// this is shorthand for { mappedCats: mappedCats }
return { mappedCats };
mappedCats itself is a valid element(s). Just return that
return mappedCats
const ChoicesList = (props) => {
const FEATURES = {
Processor: [
{
name: "17th Generation Intel Core HB (7 Core with donut spare)",
cost: 700,
},
{
name: "Professor X AMD Fire Breather with sidewinder technology",
cost: 1200,
},
],
"Operating System": [
{
name: "Ubuntu Linux 16.04",
cost: 200,
},
{
name: "Bodhi Linux",
cost: 300,
},
],
"Video Card": [
{
name: "Toyota Corolla 1.5v",
cost: 1150.98,
},
{
name: "Mind mild breeze 2000",
cost: 1345,
},
],
Display: [
{
name: '15.6" UHD (3840 x 2160) 60Hz Bright Lights and Knobs',
cost: 1500,
},
{
name: '15.3" HGTV (3840 x 2160) Home makeover edition',
cost: 1400,
},
],
};
const mappedCats = Object.keys(FEATURES).map((cat) => {
return (
<div>
<h1>{cat}</h1>
{Object.keys(FEATURES[cat]).map((item, idx) => {
return (
<div>
{`name: ${FEATURES[cat][idx].name}`}
<br></br>
{`cost: ${FEATURES[cat][idx].cost}`}
</div>
);
})}
</div>
);
});
return mappedCats;
//return (<div>{ mappedCats }</div>);
};
const domContainer = document.querySelector('#app');
ReactDOM.render(<ChoicesList />, domContainer);
<script crossorigin src="https://unpkg.com/react#16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js"></script>
<div id="app"> </div>
I have 2 moments: moment_start_date and moment_end_date.
I can figure out all holidays between those 2 moments using:
var holidays = moment_start_date.holidaysBetween(moment_end_date);
This gives me an array of moment objects, which tells me what days the holidays fall on, but it doesn't actually tell me the names of those holidays.
How do I go from a moment to a holiday name?
Most of the documentation for moment-holidays.js appears to go from a holiday name, to a date (the other direction).
We get the name of the holiday (if there is one) with the .isHoliday() method.
example: https://repl.it/#AndreasTeneketz/momentHoliday
const moment=require('moment-holiday')
const start = moment('01.01.2000','DD.MM.YYYY')
const end = moment('01.05.2000','DD.MM.YYYY')
const momentList = start.holidaysBetween(end)
const holidayList = momentList.map(momentHoliday=>({date:momentHoliday.format('DD.MM.YYYY'),name:momentHoliday.isHoliday() })
)
////// gives us //////
[ { date: '17.01.2000', name: 'Martin Luther King Jr. Day' },
{ date: '14.02.2000', name: 'Valentine\'s Day' }, { date: '21.02.2000', name: 'Washington\'s Birthday' },
{ date: '17.03.2000', name: 'Saint Patrick\'s Day' }, { date: '21.04.2000', name: 'Good Friday' },
{ date: '23.04.2000', name: 'Easter Sunday' } ]
const users =
[
{
name: "Joy soap",
customerName: "Salomy",
date: "19 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 24,
images:
"https://snack1.amazonaws.com/~asset/9d799c33cbf767ffc1a72e53997218f7"
},
{
name: "Closeup tooth paste",
customerName: "Salomy",
date: "19 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 20,
images:
"https://1.amazon4d99c3d76575cc03c2a7f816280"
},
{
name: "Iman Powder",
customerName: "Emanbe",
date: "20 March 2018",
time: "11:25am",
amount: 3000,
status: "paid",
number: 12,
images:
"https://1.amazonaws.com/~asset/ee06c63d01543a44631c3421df6ee5fa"
},
{
name: "John Bellion",
customerName: "Okonkwo Chioma",
date: "20 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 3,
images:
"https://sn1.amazonaws.com/~asset/ee06c63d01543a44631c3421df6ee5fa"
}
];
Please I have an array of objects like the above that I want to render in a ListView with a Section Header function pointing to user.date... I want it to render a list of all the items on 19 March 2018, and then render the items on 20 March 2018 under the header also.
I have used ListView several times but I have never been able to use the section header in this way with the above arrays of object. Please a detailed explanation would be greatly appreciated. I know its probably a simple task to some of you but please be kind. I need a renderSectionHeader() function that can organize the data with respect to their dates so I can render it in my listview like this
`<ListView
ref={ref => (this.scrollView = ref)}
onContentSizeChange={() => {
this.scrollView.scrollToEnd({ animated: false});
}}
dataSource={this.state.userDataSource}
renderRow={this.renderRow.bind(this)}
renderSectionHeader={this.renderSectionHeader.bind(this)}
/>`
An example of what I want is here but I want to know how it can be done with the above array
ListView is no longer available in React-Native. You can use FlatList. Its very simple then ListView as well.
1) Import FlatList from react-native:
import { FlatList } from 'react-native';
2) Copy Below code into your render() method.
<FlatList
horizontal={true/false}
style={YOUR_COSTOM_STYLE}
data={YOUR_ARRAY}
renderItem={this.renderItem.bind(this)}
keyExtractor={(item, index) => String(index)}
/>
3) You do necessary stuff for your cell in renderItem method.
// Render Methods
renderItem({ item }) {
return (
// DO_YOUR_STUFF
);
}
You can more detail about FlatList from here.
One more example for header in FlatList