Map function not working in React js component - javascript

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>

Related

I am attempting to pass a jpeg from an asset folder into a react component using .map and I am only getting the Urls

So I am trying to iterate over an array for my main page in a react project. The iteration is working but rather then rendering the images it is only returning the string. I am sure that it is something basic I am missing but not sure what to try next. this is the file i'm working with everything else is standard React...
import './App.css';
const App = () => {
const faucets = [
{ id: 1, title: 'New Leaf Carbon Project', subtext: "Tasmanian Land Conservatory. Tasmania, Australia", imageUrl: './assets/Carbon Faucet/Projects/TLC-Five-Rivers-Reserve-Credit-Matthew-Newton_02-862x689.jpeg', logo: './assets/Carbon Faucet/Projects/CERLogo.png' },
{ id: 2, title: 'Afognak Island Forest Preservation', subtext: "South Pole. Alaska, United States", imageUrl: './assets/Carbon Faucet/Projects/Afognak-Island-Forest-Preservation-Credit-Matthew-Newton_02-862x689.jpeg', logo: './assets/Carbon Faucet/Projects/South Pole Logo.png' },
{ id: 3, title: 'Crow Lake Wind Farm', subtext: "South Pole. South Dakota, United States", imageUrl: './assets/Carbon Faucet/Projects/Crow-Lake-Wind-Farm-Credit-Matthew-Newton_02-862x689.jpeg', logo: './assets/Carbon Faucet/Projects/South Pole Logo.png' },
{ id: 4, title: 'Bac Lieu Wind Farm', subtext: "South Pole. Vietnam", imageUrl: './assets/Carbon Faucet/Projects/Bac-Lieu-Wind-Farm-Credit-Matthew-Newton_02-862x689.jpeg', logo: './assets/Carbon Faucet/Projects/South Pole Logo.png' },
]
return (
<div>
{faucets.map(({title, subtext, imageUrl, logo}) => (
<div className="Project-Faucets">
<div className="Project-Banner">
{imageUrl}
<div className="Project-Logo">
{logo}
</div>
<div className="Project-Title">{title}</div>
<div className="Project-Subtext">{subtext}</div>
</div>
<div className="Project-Content">
</div>
</div>
))}
</div>
);
};
export default App;
You need to replace {imageUrl} with <img src={imageURL} />
The first one will only paste the text, the second is the correct syntax to load an image.
Same with {logo}

Astro + Svelte: two separate buttons registering a single click

I'm working with Astro and Svelte to compose a page with a product that has multiple variations. The user can select which variation they want and it'll be added to a Svelte store.
This works fine in a Svelte world, where you click the button and it adds a single product depending on which button you click REPL for this example.
However, when I render the page with Astro, and use the same Svelte component, it adds both products to the cart:
<script>
export let products = [
{
id: 1,
description: "this is a product",
prices: [
{
id: 1,
nickname: '10g',
unit_amount: 1.00,
},
{
id: 2,
nickname: '20g',
unit_amount: 2.00
}
]
},
{
id: 2,
description: "this is another product",
prices: [
{
id: 3,
nickname: '80g',
unit_amount: 18.00
}
]
}
];
</script>
<main>
{product.description && (<p>{product.description}</p>)}
{product.prices.data.map(price => (
<div class="card lg:card-side card-bordered">
<div class="card-body">
<h2 class="card-title">{price.nickname}</h2>
<p>{toCurrency(price.unit_amount)}</p>
<div class="card-actions">
<AddToCart propsData={price} product={product} client:load />
</div>
</div>
</div>
))}
</main>
(Please see Svelte REPL for <AddToCart />)
Any ideas how I get the expected behaviour? Bonus points for helping me to understand why this is happening in Astro ...
This has been fixed as of version 0.25.0.

Access a Nested array from MongoDB collection

Been racking my brains for a few days, and not getting any further forward.
I have a project using a MERN stack, and I'm trying to access a nested array from my database.
This is what my data structure looks like:
const Products = [
{
name: 'Air Zoom Pegasus 37',
brand: 'Nike',
category: 'running',
material: 'Textile & Synthetic Upper/Synthetic sole',
description: 'Hit a new PB in these mens Air Zoom Pegasus 37 trainers from Nike. In an Off Noir colourway with hits of Blue Fury and Bright Crimson, these runners have lightweight mesh upper for a breathable feel. They feature a secure lace up fastening and are sat on a soft foam midsole for long-lasting cushioning and maximum responsiveness. With Nikes Air Zoom unit at the forefront for a smooth ride, these trainers are finished with a grippy rubber tread and the iconic Swoosh logo to the sidewalls.',
price: 105,
sizes: [
{ size: '6', countInStock: 10 },
{ size: '7', countInStock: 10 },
{ size: '8', countInStock: 10 },
{ size: '9', countInStock: 10 },
{ size: '10', countInStock: 10 },
{ size: '11', countInStock: 10 },
{ size: '12', countInStock: 10 }
],
image1: '/images/nike_pegasus37_1.jpeg',
image2: '/images/nike_pegasus37_2.jpeg',
image3: '/images/nike_pegasus37_3.jpeg',
image4: '/images/nike_pegasus37_4.jpeg',
image5: '/images/nike_pegasus37_5.jpeg',
image6: '/images/nike_pegasus37_6.jpeg',
rating: 0,
numReviews: 0,
tags: 'nike, adidas, running, trainers, 5k, new, style',
},
]
I can't seem to access the nested objects in the 'Sizes' array. All the properties are returned in the state using Redux and I can see that the data payload returns all items from this BSON list in my Redux Devtools on Chrome.
I'm retrieving this data using Axios from a MongoDB collection, and using Redux to manage my state using dispatch and selector. Everything else works. I can fetch every other piece of information so I know it's not a back end problem, but I just can't seem to figure out how to map that array out.
Any help would be much appreciated.
Thanks,
Liam.
To map an array in react you can do it like this
Component start......
return {
<div>
{
// First map over your Products
// note the ? is there to prevent it from crashing if Products is not defined
Products?.map(product => {
return <>
<p>{product.name}</p>
//then map over this products sizes
<div>
{product?.sizes.map(size => {
return <p>{size.size} - {size.countInStock}</p>
})}
</div>
</>
})
}
</div>
}

Issues with an object- Will not map

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>

Why is my JavaScript object property inaccessible, when it IS, in fact, defined?

Here is the object. It is a second-level object in the data tree:
user: {
userId: 3,
username: 'aragorn',
},
My React component is destructuring its parent object and making it available to the entire component. When I render the full user object using this code:
<p className="small">
{`Submitted by ${JSON.stringify(user)}`}
</p>
I get a complete stringified object with all of user's properties:
When I try to access only the 'username' property from the 'user' object:
<p className="small">
{`Submitted by ${JSON.stringify(user.username)}`}
</p>
I get this error:
Have you ever faced this weird issue before?
For further study, here is the full data object. This is coming from a mock data object being exported from a neighboring file in the same app. No network requests to a backend or anything, so there shouldn't be any async stuff going on here (I may be wrong):
{
title: "The Hefalump's Tale",
page: '32',
line: '1',
author: 'Joni E. Driskill',
genre: 'Sci-fi',
type: 'Motivational',
content: 'The grass is greener on the other side, unless, in actuality and reality, it is not. I guess in that case, you can just give up on anything nice in life.',
claps: 23,
id: 4,
user: {
userId: 3,
username: 'aragorn',
},
comments: [
{
commentId: 0,
quoteId: 0,
content: 'Comment content',
userId: 'userId',
claps: 2,
date: 2,
},
{
commentId: 1,
quoteId: 1,
content: 'Comment content',
userId: 'userId',
claps: 4,
date: 1,
},
{
commentId: 2,
quoteId: 2,
content: 'Comment content',
userId: 'userId',
claps: 12,
date: 0,
},
],
},
And HERE is my React component, called 'Meta,' bringing in the 'quote' object as a prop. The primary line in question is toward the bottom, but feel free to look at my props destructuring, too, if you like:
import React from 'react';
import Clap from '../mechanics/Clap';
import Report from '../mechanics/Report';
const Meta = ({
quote: {
content,
title,
author,
page,
line,
genre,
type,
claps,
id,
user,
},
}) => (
<div className="discussion-meta mb2">
<h1>“{content}”</h1>
<hr />
<div className="columns is-spaced-around pb3 text-align-left">
<div className="column">
<h3>{title}</h3>
<p>
<small>by {author}</small>
</p>
{page ?
<p>
<small>page {page}{line ? `, line ${line}` : ''}</small>
</p>
: null
}
</div>
<div className="column text-align-right">
<p>
<span className="tag-purple small">{genre}</span>
</p>
<p>
<span className="tag-green small">{type}</span>
</p>
</div>
</div>
<div className="columns">
<div className="column">
<p className="small">
{`Submitted by ${JSON.stringify(user.username)}`}
</p>
</div>
</div>
<div className="columns">
<div className="column">
<Clap claps={claps} />
</div>
<div className="column">
<Report id={id} />
</div>
</div>
</div>
);
export default Meta;
I've recreated in CodeSandbox, and it works! WTF!
https://codesandbox.io/s/4q9nlywl1x

Categories