map over nested array in react - javascript

I want to display the values of the following data which is received when i make fetch request:
data: Array
0: Object
title: "html"
description: Array
name: "xyz"
class: "c"
1: Object
title: "html1"
description: Array
name: "xyz1"
class: "c1"
I have tried following code:
<div>
{
data.map((item, index) => {
<h1 key={index}>{item.title}/</h1>
{ item.description.map((c, i) =>
<div>
<h3 key={i}>{c.name} {c.class}</h3>
</div>
)}
})
}
</div>
The above code displays only the title value. It's not displaying name and class value. Please help me.

You were not returning anything to your data.map
{data.map((item, index) => {
return (
<div>
<h1 key={index}>{item.title}/</h1>
{item.description.map((c, i) => (
<div>
<h3 key={i}>
{c.name} {c.class1}
</h3>
</div>
))}
</div>
);
})}

If description is an object then you don't need to map over description again
this alone should do
<div>
{
data.map((item, index) => {
<h1 key={index}>{item.title}/</h1>
<div>
<h3>{item.description.name} {item.description.class}</h3>
</div>
})
}
</div>

Related

Nested Map is not working properly on react template

I am trying to mapping through three objects in react to render multiple categories on react template , Code doesn't give any error but its not showing any content on react web page.
return (
<div className="container pt-80">
<center>Category Grouping</center>
{categories.map((cate,key)=>{
subCategories.map(subCate=>{
if(subCate.category === cate.id){
pType.map(ptype=>{
if (ptype.category === subCate.id){
console.log("Category : ",cate.category)
console.log("Sub Category : ",subCate.subCatName)
console.log("Product Type : ",ptype.ptype)
console.log("*******************************************")
return(
<Fragment>
<h1 style={{marginLeft:"30px"}}>{cate.category}</h1>
<h1 style={{marginLeft:"60px"}}>{subCate.subCatName}</h1>
<h1 style={{marginLeft:"120px"}}>{ptype.ptype}</h1>
</Fragment>
)
}
})
}
})
})}
</div>
)
Its printing the correct values in console :
Extending what #Akhil said in the comment. You are actually not returning anything in you're first two map calls, only the last.
add return before both nested map calls:
return subCategories.map(subCate=>{...
and
return pType.map(ptype=>{
Also I would add a return null after your if statements. Map expects a return value.
if(subCate.category === cate.id){
....
}
return null;
and
if (ptype.category === subCate.id){
....
}
return null;
Look into the comment by #Akhil. You missed the return for the map.
const categories = [{ id: 1, category: "Foods & Supplements" }];
const subCategories = [{ id: 1, category: 1, subCatName: "Herbal Drinks" }];
const pType = [
{ id: 1, category: 1, ptype: "Herbal Juice" },
{ id: 2, category: 1, ptype: "Herbal Coffee Tea&Soup" }
];
export default function App() {
return (
<div>
<h1>Category Grouping</h1>
{categories.map((cate, key) => (
<div key={key}>
{subCategories.map((subCate, sKey) => (
<div key={sKey}>
{subCate.category === cate.id &&
pType.map((ptype, pKey) => (
<div key={pKey}>
{ptype.category === subCate.id && (
<>
<h1 style={{ marginLeft: "30px" }}>{cate.category}</h1>
<h1 style={{ marginLeft: "60px" }}>
{subCate.subCatName}
</h1>
<h1 style={{ marginLeft: "120px" }}>{ptype.ptype}</h1>
</>
)}
</div>
))}
</div>
))}
</div>
))}
</div>
);
}
Also, use some sort of linting (e.g. Eslint) and format the code, both will help to catch syntax errors.

How can I bold text within an object array items string?

I am using the data from below to pass as props in React. Everything works fine but I need to only bold the words "target audience" in the text property. Is there a way to do this?
const SlideData = [
{
index: 1,
title: "Target Audience",
text: [
"The target audience for this course is anyone who is assigned roles as a HR Employee Maintainer...",
],
image: {
src: targetAudience,
width: imageSize,
},
},
index: 2,
title: "Reporting ",
text: [
"Reporting Manager is designated to...",
],
image: {
src: reporting,
width: imageSize,
},
},
]
export default SlideData
Added Render Component
const TextSlide = ({ title, text = [], list, image }) => {
return (
<>
<div className="slide">
<div className="standard-grid">
<span className="slide-title title">{title}</span>
<div className="content">
{text.map((t, i) => (
<p key={i} className="text">
{t}
</p>
))}
</div>
{image ? <img className="picture" src={image.src} style={{ maxWidth: image.width }} alt="image" /> : null}
</div>
</div>
</>
);
};
export default TextSlide;
``
You could split the text by target audience, and map the chunks inbetween to text nodes appending a node to each element:
"The target audience for this course is anyone who is assigned roles as a HR Employee Maintainer...",
.split("target audience")
.map((text, index) => <>{index !== 0 && <b>target audience</b>} {text}</>)
A more sophisticated approach would be to inject html tags into the text, and use dangerouslySetInnerHTML:
const formatted = text.replace(/(target audience)/g, it => `<b>${it}</b>`);
return <div dangerouslySetInnerHTML={formatted} />;
You could change the text to an object with a key of __html and use bold tags to render it by using dangerouslySetInnerHTML:
const SlideData = [
{
index: 1,
title: "Target Audience",
text: [
{
__html:
"The <b>target audience<b> for this course is anyone who is assigned roles as a HR Employee Maintainer...",
},
],
image: {
src: targetAudience,
width: imageSize,
},
},
];
const TextSlide = ({ title, text = [], list, image }) => {
return (
<>
<div className="slide">
<div className="standard-grid">
<span className="slide-title title">{title}</span>
<div className="content">
{text.map((t, i) => (
<p key={i} className="text" dangerouslySetInnerHTML={t} />
))}
</div>
{image ? (
<img
className="picture"
src={image.src}
style={{ maxWidth: image.width }}
alt="image"
/>
) : null}
</div>
</div>
</>
);
};
Here is a small codepen for demonstration.
Try this:
text: ["The ", <strong>target audience</strong>, " for this course is anyone who is assigned roles as a HR Employee Maintainer..."]
React will render this as a string with the HTML tags applied.

showing only first element from data

Hi all I have following code: my code
In this scenario I am receiving some data from backend
const attachments = [
{
id: 1,
name: "someURLL_Name_1",
link: "https://someURLL_Name_1",
img: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg"
},
{
id: 2,
name: "someURLL_Name_2",
link: "https://someURLL_Name_2",
img: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg"
},
{
id: 3,
name: "someURL_Name_3",
link: "https://someURLL_Name_3",
img: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg"
}
];
I need to map them all and show only first element form my data, and show with numbers rest hided data.
In the end it should be like something like this:
someURL_Name_1 https://someURLL_Name_1 +2 more
I successfully mapped all my data and write little logic for + more.
<div className={Styles.attachments}>
{data.map((item) => {
return <Attachment key={item.id} data={item} image={item.img} />;
})}
{data.length > 1 && (
<span className={Styles.more}>+{data.length - 1} more</span>
)}
</div>
Please help me to resolve a problem. Again, I want to show only first element , and then if there are another elements then I should hide them and show hide elements with numbers.
Thanks.
Just don't map over all entries then. The following will work :-
export const Attachments = ({ data }) => {
return (
<div className={Styles.attachments}>
{data[0] && (
<Attachment key={data[0].id} data={data[0]} image={data[0].img} />
)}
{data.length > 1 && (
<span className={Styles.more}>+{data.length - 1} more</span>
)}
</div>
);
};

Render products grouped by category

Good evening readers!
I'm working to a simple shopping cart single page application using react and redux!
That's the situation:
listOfCategories: ["Basic", "Hardware"]
listOfItems : [
{
fields: {
category: "Basic",
name: "Starter",
...
},
...
},
{
fields: {
category: "Basic",
name: "Entertainment",
...
},
...
},
{
fields: {
category: "Hardware",
name: "STB",
...
},
...
}
]
In my component, inside the render method, there is:
render() {
return (
<div>
<div>
Catalog
{this.props.listOfItems.map(item => (
<Product
id={item.fields.productexternalid}
name={item.fields.productname}
category={item.fields.SKYDE_Product_Category__c}
clicked={() => this.addToCart(item)}
costOneTime={item.fields.baseonetimefee}
costRecurring={item.fields.baserecurringcharge}
eligible={item.fields.eligible}
visible={item.fields.visible}
></Product>
))}
</div>
</div>
);
}
The result is something like this:
I just want to render an accordion filled with the category name, items grouped by category under the accordion:
Basic --> item.category
Starte --> item.name
Entertainment --> item.name
Hardware --> item.category
STB --> item.name
.map() and .filter() function will be useful, but i don't really know how to manage this case.
Any help will be appreciated!
map() and filter() are definitely useful in this case.
render() {
// in case "listOfCategories" is not predefined
let listOfCategories = listOfItems.map(item => item.fields.category)
// sort and remove duplicates
listOfCategories = listOfCategories.sort().filter((v, i) => listOfCategories.indexOf(v) === i);
return (
<div>
{listOfCategories.map(cat => (
// You probably had this `Category` component around
<Category key={cat} name={cat} {...catProps}>
{listOfItems.filter(item => item.fields.category === cat).map(item => (
<Product
key={item.fields.id}
id={item.fields.id}
name={item.fields.name}
{...itemProps}
/>
))}
</Category>
))}
</div>
);
}
Basic
<div>
Basic
{this.props.listOfItems.filter(item => item.fields.category ==="Basic").map(item => (
<Product
id={item.fields.productexternalid}
name={item.fields.productname}
category={item.fields.SKYDE_Product_Category__c}
clicked={() => this.addToCart(item)}
costOneTime={item.fields.baseonetimefee}
costRecurring={item.fields.baserecurringcharge}
eligible={item.fields.eligible}
visible={item.fields.visible}
></Product>
))}
</div>
Hardware
<div>
Basic
{this.props.listOfItems.filter(item => item.fields.category ==="Hardware").map(item => (
<Product
id={item.fields.productexternalid}
name={item.fields.productname}
category={item.fields.SKYDE_Product_Category__c}
clicked={() => this.addToCart(item)}
costOneTime={item.fields.baseonetimefee}
costRecurring={item.fields.baserecurringcharge}
eligible={item.fields.eligible}
visible={item.fields.visible}
></Product>
))}
</div>

Render object arrays in react function

Forgive me, I'm a react noob. I'm trying to access the data inside a javascript/react object. The json data looks like this:
"schoolData": {
"student": [
{
"name": "blah",
"type": "lorem",
"grade": 90,
}
],
"class": null
},
What I'm trying to display is essentially just like this...
Student
name: Blah type: lorem grade: 90
Class
--- no data here ---
So I'm trying like this:
import React, { PropTypes } from 'react';
const SchoolDataPropTypes = {
SchoolData: PropTypes.object.isRequired,
};
function School(props) {
return (
<div className="section">
<h3 className="head">School Data</h3>
<div className="row">
<ul className="Uli">
{(props.data || []).map(function(value) {
return <label>{props.data.key}</label><li key={value}>{key}: {value}</li>
})}
</ul>
</div>
</div>
);
}
School.propTypes = SchoolPropTypes;
export default School;
It obviously doesn't work. So that I can render each array inside the object?
Ideally, you would manually specify each key.
{(schoolData.student || []).map(student => (
<ul className="Uli">
<li>Name: {student.name}</li>
<li>Grade: {student.grade}</li>
</ul>
))}
etc...
But if you really want to loop through variable keys in the student object then basically you need to loop through the student array, and then loop through the keys in each student object. Here's what it might look like:
const School = ({ schoolData }) => (
<div className="section">
<h3 className="head">School Data</h3>
<div className="row">
{(schoolData.student || []).map(student => (
<ul className="Uli">
{Object.keys(student).map(key => (
<li key={key}>{key}: {student[key]}</li>
))}
</ul>
))}
</div>
</div>
);
-
<School schoolData={schoolData} />
If you're targeting very, very old browsers you may need a polyfill for Object.keys

Categories