How can I render the nested data in ReactJS? - javascript

I have the bellow alike data, and I would like to render them.
Let's say I would like to display firstName, address, and seatType and flightId for each flight the passenger has.This has to be done for each passenger. How can I achieve that?
Updated
[
{
"id": 1,
"firstName": "Smith",
"lastName": "John",
"address": [
"1 Street",
"YYY",
],
"flights": [
{
"flightId": 1,
"seatType": "oridinary"
},
{
}
]
},
{},
]
Here is my code
render() {
const { data } = this.state;
return (
<div>
{" "}
{Object.keys(data).map((key, index) => (
<p key={index}>
{" "}
{key} {data[key].flights}
{data[key].flights.map(k => (
{data[key].flights[k]}
))}
</p>
))}
</div>
);
}

I'm assuming you're looking for something like this:
return (
<div>
{
passengers.map(passenger => {
if (!passenger.id) { return null } /* + */
return (
<div key={passenger.id}>
<span>{passenger.firstName} {passenger.lastName}</span>
<div>
<span>Passenger's Flights</span>
{
passenger.flights && /* + */
Array.isArray(passenger.flights) && /* + */ passenger.flights.map(flight => {
if (flight.flightId) {
return (
<div key={flight.flightId}>
{flight.seatType}
</div>
)
}
return null
})
}
</div>
</div>
)
})
}
</div>
);
}
Note: remember that you should not use index as a key.
Edit: You need to add a null/undefined check

render() {
const { data } = this.state;
return (
<div>
{data.map((passenger, index) => (
<p key={index}>
{passenger.firstName} {passenger.address.join(' ')}
{passenger.flights.map(flight => (
<p>{flight.seatType} {flight.flightId}</p>
))}
</p>
))}
</div>
);
}

render() {
const { data } = this.state;
return (
<div>
{data.map(({id, firstName, address, flights}) => (
<p key={id}>
<div>{firstName}</div>
<div>{address.join(', ')}</div>
{flights.map(f => (<div key={f.flightId}>{f.flightId}-{f.seatType}</div>))}
</p>
))}
</div>
);
}
Not sure if it compiles but it's something like this. Also, if you have an ID, use it as key.

Related

two React Componets in One section we upload image and can increase the number of input other section we will preview those images

I am working on a page
have two sections. In one section we upload image and can increase the number of input, in the other section we will preview the image.
I don't know I am not getting the right id that I want to edit.
we can add more fields on click of button and remove then at the end post data at api endpoint?
RightSection
const RightSection = ({ inputImage, setInputImage }) => {
const handleAddFields = () => {
if (inputImage.length <= 9) {
const values = [...inputImage];
values.push({
id: values.length + 1,
name: `Drop Image ${values.length + 1} Here`,
});
setInputImage(values);
}
};
const handleRemoveFields = () => {
if (inputImage.length > 3) {
const values = [...inputImage];
values.splice(values.length - 1, 1);
setInputImage(values);
}
};
const handleInputChange = (id, event) => {
console.log(id, event.target.id, "=====");
const newInputFields = inputImage.map((i) => {
if (id === i.id) {
i.url = URL.createObjectURL(event.target.files[0]);
i.name = event.target.files[0].name;
// push image object in array
setInputImage([
...inputImage,
{
id: id,
url: URL.createObjectURL(event.target.files[0]),
name: event.target.files[0].name,
},
]);
}
return i;
});
setInputImage(newInputFields);
};
console.log(inputImage);
return (
<>
<div id="right" className="flex">
<div className="margin">
<div className="inlineflex">
<H1>Background Image</H1>
<div>
<AddIcon onClick={handleAddFields} />
<RemoveIcon onClick={handleRemoveFields} />
</div>
</div>
</div>
<div
style={{
margin: "0 auto",
position: "relative",
width: "80%",
}}
>
{inputImage.map((inputField, index) => (
<FileInput key={index}>
<label
htmlFor={inputField.id}
onClick={(e) => {
console.log("click", index + 1);
}}
>
{inputField.name}
</label>
<input
id={index + 1}
onChange={(event) => handleInputChange(inputField.id, event)}
accept="image/*"
type="file"
/>
</FileInput>
))}
</div>
</div>
</>
);
};
LeftSection
const LeftSection = ({ inputImage }) => {
return (
<>
<div id="left" className="flex">
<div className="margin">
<H1>Preview</H1>
</div>
<Grid>
{Array.isArray(inputImage) &&
inputImage.map((item, index) => {
if (item?.url?.includes("http") || item?.url?.includes("https")) {
return (
<div key={index}>
<img src={item?.url} alt={item?.name} />
</div>
);
}
})}
</Grid>
</div>
</>
);
};
BackgroundImage
let initaValue = [
{ id: 1, name: "Drop Image 1 Here", url: "" },
{ id: 2, name: "Drop Image 2 Here", url: "" },
{ id: 3, name: "Drop Image 3 Here", url: "" },
];
const BackgroundImage = () => {
const [inputImage, setInputImage] = useState(initaValue);
return (
<>
<Container>
<RightSection inputImage={inputImage} setInputImage={setInputImage} />
<LeftSection inputImage={inputImage} setInputImage={setInputImage} />
</Container>
</>
);
};
export default BackgroundImage;
I think there is some issue with the handleInputChange function on the RightSection component.
Somehow I am not able to update the item with the correct id in the array.
Is there any other efficient solution for this problem?

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 to map image array with filter in ReactJS

I'm absolutely beginner in ReactJS and I want to filter and map
const Shop = [
{
img : jam,
category: 'jam'
},
{
img : headset,
category:'headset'
},
{
img : sepatu,
category:'sepatu'
}
];
let ShopItem = [
{
id : 1,
img : jam,
category : 'jam',
price : 'Rp. 900,000'
},
{
id : 2,
img : jam,
category : 'jam',
price : 'Rp. 900,000'
},
{
id : 3,
img : headset,
category : 'headset',
price : 'Rp. 900,000'
}
]
function Content(){
const [shopItems,toogleshopItems]=useState(false);
let [items,showItems]=useState('');
const toogleShop = ()=>{
toogleshopItems(!shopItems);
console.log(shopItems);
}
function showshopItems(){
return(
<>
{Shopitem.map((shopitem, shopitemIndex) => {
return Shop.map((shop, shopIndex) => {
if (shop.category == shopitem.category)
return <img className="image-place" src={shopitem.img} />;
});
})}
</>
)
}
return(
<>
<div className="content">
<div className="content-wrapper">
<div className="content-title">Browse Categories</div>
<div className="image-flex">
{
Shop.map((shops)=>
<React.Fragment key={shops.category}>
<img onClick={toogleShop} className="image-place" src={shops.img}/>
</React.Fragment>
)}
</div>
<hr/>
{shopItems? showshopItems() : console.log("no") }
</div>
</div>
</>
)
}
export default Content
how to map shopitem image that has the same category value with shop category value...
when I click picture watch
if I click the picture 1 it will show child picture that has category jam
Finally I found out whats your problem. You should have a state for getting current category when user clicks on the top image and filter the items based on the state. I've created a sample based on your request:
export default function App() {
const [currentCategory, setCategory] = useState();
const TopSlide = () => {
return (
<div className="topSlide">
{Shop.map((shop, index) => {
return (
<img
alt=""
className="topSlideImage"
src={shop.img}
onClick={() => {
setCategory(shop.category);
}}
/>
);
})}
</div>
);
};
const DownSlide = () => {
return (
<div className="downSlide">
{ShopItem.filter((x) => x.category === currentCategory).map(
(shop, index) => {
return <img alt="" className="downSlideImage" src={shop.img} />;
}
)}
</div>
);
};
return (
<div className="App">
{TopSlide()}
<hr />
{DownSlide()}
</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>

Props data are not rendering

I have a problem rendering my props data
Here I'm trying to pass props to a component with mapped data from a sample data set
const weatherComponents = weatherData.items.map(weather => {
return(
<div key={weather.forecasts.area}>
<WeatherForecast
name={weather.forecasts.area}
condition={weather.forecasts.forecast}>
</WeatherForecast>
</div>
)})
return(
{weatherComponents} )
This is the component
function WeatherForecast(props) {
return(
<div>
<p>Name: {props.name}</p>
<p>Condition: {props.condition}</p>
</div>
)}
This is the sample data set
{
"area_metadata": [
{
"name": "Yishun",
"label_location": {
"latitude": 1.418,
"longitude": 103.839
}
}
],"items": [
{
"forecasts": [
{
"area": "Yishun"
"forecast" : "cloudy"
}
]}
]}
In my browser, it shows Warning: Each child in a list should have a unique "key" prop. and the data are not rendering, it only appears "Name: " without the area name from the data set. Am I mapping the data in the wrong way? Help TT
You have 2 options ... well, 3.
You need an array in "area_metadata" and "items":
1.1. The fast solution:
const weatherComponents = weatherData.items.map(weather => {
return(
<div key={weather.forecasts[0].area}>
<WeatherForecast
name={weather.forecasts[0].area}
condition={weather.forecasts[0].forecast}>
</WeatherForecast>
</div>
)
})
return({weatherComponents})
1.2 The right solution:
const weatherComponents = weatherData.items.map(weather => {
return weather.forecasts.map( casts => (
<div key={casts.area}>
<WeatherForecast
name={casts.area}
condition={casts.forecast}>
</WeatherForecast>
</div>
))
})
return({weatherComponents})
2. You do not need an array:
{
"area_metadata": [
{
"name": "Yishun",
"label_location": {
"latitude": 1.418,
"longitude": 103.839
}
}
],
"items": [
{
"forecasts": {
"area": "Yishun"
"forecast" : "cloudy"
}
}
]
}
Just replace
const weatherComponents = weatherData.items.map(weather => {
return(
<div key={weather.forecasts.area}>
<WeatherForecast
name={weather.forecasts.area}
condition={weather.forecasts.forecast}>
</WeatherForecast>
</div>
)})
return(
{weatherComponents} )
with
const weatherComponents = weatherData.items.map(weather => {
const {area, forecast} = weather.forecasts[0];
return(
<div key={area}>
<WeatherForecast
name={area}
condition={forecast}>
</WeatherForecast>
</div>
)})
return(
{weatherComponents} )

Categories