map function not working properly in object React - reactjs

I have an array that contains as follows. I have successfully mapped the data and put it into the elements. but there are some values I couldn't get correctly. I have added a console.log to figure out the data. data is correct in the array, I want to get the Seats ("A1,B1") in here <h5><small>{seatNos.seats}</small></h5> but nothing is displaying. appreciate any help.
Data array
"data": {
"userBookings": [
{
"transactionId": 6357604,
"totalAmount": 350,
"createdAt": "2021-08-05 02:16:48",
"movieName": "Mortal Kombat",
"theaterName": "XxX Cinema",
"showTime": "17:30",
"refcode": "0016048GIN210805I",
"bookedSeats": [
{
"seatType": "Comfert",
"seats": "A1,B1",
"childTickets": 1,
"totalTickets": 2,
"bookedDate": "2021-08-05"
}
]
}
]
},
code
<div className="col-xl-5 col-lg-5 col-md-7 col-sm-7 col-xs-9 col-6" style={{paddingLeft:25}}>
<h5><b>{bookingsData.movieName}</b></h5>
<h5>{bookingsData.theaterName}</h5>
<h5><small>{bookingsData.showTime}</small></h5>
{bookingsData.bookedSeats.map((seatNos) => {
console.log(seatNos.seats);
<h5><small>{seatNos.seats}</small></h5>
})}
{/* <h5><small>{bookingsData.bookedSeats.seats}</small></h5> */}
</div>

You need to return element in map, and set key for this element:
{bookingsData.bookedSeats.map((seatNos, index) => {
console.log(seatNos.seats);
return <h5 key={index}><small>{seatNos.seats}</small></h5>
})}

Your arrow function inside the .map() doesn't return a value. You need a return before the JSX:
{bookingsData.bookedSeats.map((seatNos) => {
console.log(seatNos.seats);
return <h5><small>{seatNos.seats}</small></h5>
})}
Or to use the implicit return arrow function syntax (Either round brackets, or no brackets: () => () or () => returnedValue)
{bookingsData.bookedSeats.map((seatNos) => <h5>
<small>{seatNos.seats}</small>
</h5>)}

This is because you forgot the return
array.map((item) => {
return (
<p>{item.value}</p>
)
})

Related

React | How to render only 1 object from an array that is part of a nested object

I have this data structure:
const data = [
{
title: 'title',
description: 'description'
images: [
{ mainImg: 'url' },
{ img1: 'url' },
{ img2: 'url' },
{ img3: 'url' },
],
},
...
]
My question is, how can I render only the mainImg separated from the others? And how can I render the other images without the mainImg.
What I've tied so far is to map through the images like this: (I did mapped through data before)
{data.images.map((img, index) => (
<img
key={`image${index}`}
src={img.mainImg}
className={styles.mainImg}
/>
))
}
This worked, but the issue is that I map through all the images and when I open the consoles, all the images are rendered but they are not visible because they don't have the src tag. (I think).
Simply trying to use data.images.mainImg as the src value doesn't render anything, and also does not throw any errors.
Also, I have an issue trying to render all the other images except the mainImg. This is what I've tried but I get lost and I don't know what the src value should be.
{data.images
.filter((img) => img.mainImg != project.images.mainImg)
.map((img, index) => (
<img src={img} />
))
}
You could use hasOwnProperty : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
data.images.map((e, i) => {
if (e.hasOwnProperty('mainImg')) {
// Do something with mainImg
}
//Do something with the others
})
A JSfiddle with example : https://jsfiddle.net/RyanZee/hu189jxd/12/
Do you always have a mainImg at index 0? If so you can use
const [firstImg, ...imgs] = data.images;
return (
<>
<img src={firstImg.mainImg} ... />
{ imgs.map((img, index) => <img src={img[`img${index + 1}`]} /> }
</>
)

Deleting nested array element from a react state variable, doesn't update the state value in UI but has the updated value

I am new with react and working on a project where I am using the following
const [skillSet, updateSkillSet] = useState([{
skillType : '',
skillDescr : [
{
skillName : '',
skillExp : ''
}
]
}])
when elements are added array looks like
[
{
"skillType": "fe",
"skillDescr": [
{
"skillName": "s1",
"skillExp": "3"
},
{
"skillName": "s2",
"skillExp": "3"
},
{
"skillName": "s3",
"skillExp": "2"
}
]
},
{
"skillType": "be",
"skillDescr": [
{
"skillName": "b1",
"skillExp": "2"
},
{
"skillName": "b2",
"skillExp": "2"
},
{
"skillName": "b3",
"skillExp": "2"
}
]
}
]
when I add an element to the skillDescr array it's working fine and it's rendering properly in the UI. But when I delete an element from skillDescr, the values that gets removed from the array is correct(the one which I am trying to delete) but in the UI the last element is being removed.
output(UI) after deleting s2,b2
array after deleting s2,b2
This is the code I am using to delete the element
function deleteSkill(e, index, index1){
e.preventDefault()
skillSet[index].skillDescr = skillSet[index].skillDescr.filter((_,i)=>i!=index1)
updateSkillSet(skillSet)
}
I have index, index1 as there are two arrays
I am using map to render the UI
here is the code
{
skillSet.map(({skillType, skillDescr},index)=>{
return(
<div key={index} className='skills__box'>
<div className='skill__type'>
<input placeholder='Skill set name' onChange={(e)=>{updateSkilltype(e,index)}}></input>
{
skillDescr.map(({skillName, skillExp},index1)=>{
return(
<div key={index1} className='skill__name'>
<input placeholder='Skill name' onChange={(e)=>{updateSkillname(e, index, index1)}} required></input>
<input placeholder='Experiece Level' onChange={(e)=>{updateSkillexp(e, index, index1)}} type='number' required></input>
<AiTwotoneDelete onClick={(e)=>{deleteSkill(e, index, index1)}}/>
</div>
)
})
}
<button onClick={(e)=>{addSkill(e,index)}} className='btn btn-primary'>Add skill</button>
</div>
</div>
)
})
}
So my problem here is the array is getting updated properly but the render that's happening after the state update is not correct
That is because React doesn't know which element got removed. You need to add a key prop to all elements that correspond with the data rendered inside the loop so React can compare properly. Always try to prevent indices as key's.
Using something unique and stable, like an ID, would be even better.
{
skillSet.map(({skillType, skillDescr},index)=>{
return(
<div key={skillType} className='skills__box'>
<div className='skill__type'>
<input placeholder='Skill set name' onChange={(e)=>{updateSkilltype(e,index)}}></input>
{
skillDescr.map(({skillName, skillExp},index1)=>{
return(
<div key={skillName} className='skill__name'>
<input placeholder='Skill name' onChange={(e)=>{updateSkillname(e, index, index1)}} required></input>
<input placeholder='Experiece Level' onChange={(e)=>{updateSkillexp(e, index, index1)}} type='number' required></input>
<AiTwotoneDelete onClick={(e)=>{deleteSkill(e, index, index1)}}/>
</div>
)
})
}
<button onClick={(e)=>{addSkill(e,index)}} className='btn btn-primary'>Add skill</button>
</div>
</div>
)
})
}
For your delete function, map through the state array and just return the element unless it is the item at the index you want. If it is the index, return a copy of the item with the update skillDescr array.
function deleteSkill(e, index, index1){
e.preventDefault()
updateSkillSet(prev=>
prev.map((item,i)=>{
if(i === index){
return {...item,
skillDescr:item.skillDescr.filter((_,j)=>j!==index1)
}
}
//not the index, just return the item
return item
})
)
}

Loop over Json object -- React

I have a API for which I would like to loop over to get all the value of its keys. But unfortunately Iam only getting the keys for it.
My code until now:
...
const image_link = JSON.stringify(image);
const parsed_link = JSON.parse(image_link);
console.log('1st link', parsed_link[0].Header) // gives "abc.jpg"
...
...
<div>
{
Object.keys(parsed_link).map((e, i) => {
console.log(parsed_link);
console.log(e); // gives integers like 0,1,2 etc...
console.log(i); // gives integers like 0,1,2 etc...
<img src={e} alt="something" width="300" height="200" />;
return null;
})
}
</div>
...
...
API looks like this:
"Header": [
{
"image": "abc.jpg"
},
{
"image": "xyz.jpg"
},
{
"image": "lmn.jpg"
}
]
Please suggest, where am I goin wrong.
Thanks in advance
If you want to loop through an array, you can use map function.
If you want to loop through an object, you can have to convert the object into an array using Object.keys(YOUR_OBJECT) (if you want to get the key) or Object.values(YOUR_OBJECT) (if you want to get the values) than use map function.
You can directly print the array of data into an array of views. You have to return a view like these:
YOUR_ARRAY.map((item, index) => (
<div>YOUR VIEW</div>
))
// or
YOUR_ARRAY.map((item, index) => {
return(
<div>YOUR VIEW</div>
)
})
Note: you can only return a single parent view inside the return value. If you want to return multiple views inside the return value, you have to wrap them inside a single <div></div> or <React.Fragment></React.Fragment> or <></> parent.
In your code, I saw you wrote parsed_link[0].Header. So I assume that the API returns something like this:
[
{
"Header": [
{
"image": "abc.jpg"
},
{
"image": "xyz.jpg"
},
{
"image": "lmn.jpg"
}
],
...
},
...
]
Here is my answer:
<div>
{
parsed_link[0]['Header'].map((item, index) => (
<img
key={index}
src={item}
alt='something'
width='300'
height='200'
/>
)
}
</div>

Comma to New Line

In React, how can I turn , characters into new lines?
Suppose we have an array like this:
const items = [
{
label: "Animals",
value: "Puppies, Kittens, Bunnies"
},
// ...
];
And we display it like this:
<div>
{items.map(item => (
<div style="left">
{item.label}
</div>
<div style="right">
{item.value}
</div>
))};
</div>
How can I turn all , characters in the value keys of the array items into new lines?
Current Output:
Animals Puppies, Kittens, Bunnies
Desired Output:
Animals Puppies
Kittens
Bunnies
{item.value.split(", ").map((line, i) => <div key={i}>{line}</div>)}
is the simplest, if putting each item in a div is okay for you.
The other, more complex option is to add <br>s between each line, and wrap those in a React.Fragment:
function addBrs(items) {
const children = [];
items.forEach((item) => {
children.push(item);
children.push(<br />);
});
children.pop(); // Remove last extraneous BR
return React.createElement(React.Fragment, {}, ...children);
}
// ...
{addBrs(item.value.split(", "))}}

How to .map render list of items grouped into category in React

Hello guys i wanted to render some items into their own category using .map, but i dont know how to do it . I only know how to render standard list. Below is the example of my data:
[
{
"id_kategoriTest": 1,
"kategori": "Hematologi",
"id_jenisTest": 24,
"jenis": "Coombs Test Direct"
},
{
"id_kategoriTest": 1,
"kategori": "Hematologi",
"id_jenisTest": 25,
"jenis": "Hb Elektroforesis"
},
{
"id_kategoriTest": 14,
"kategori": "Imuno-Serologi",
"id_jenisTest": 247,
"jenis": "Anti HBs Titer"
},
{
"id_kategoriTest": 14,
"kategori": "Imuno-Serologi",
"id_jenisTest": 248,
"jenis": "Anti HBc"
}
]
The output i wanted is like this:
Hematologi
Coombs Test Direct
Hb Elektroforesis
Imuno-Serology
Anti HBs Titer
Anti HBc
Thanks.
First step is to sort your array to something more convenient.
Then render the sorted array.
Here, myArray contain your array above
const sorterAR = [];
myArray.forEach((item) => {
let cat = sorterAR.find(
(cat) => cat.id_kategoriTest === item.id_kategoriTest
);
if (!cat) {
cat = {
id_kategoriTest: item.id_kategoriTest,
kategori: item.kategori,
items: [],
};
sorterAR.push(cat);
}
cat.items.push(item);
});
return (
<div className="App">
{sorterAR.map((cat) => (
<>
<div>
<b>{cat.kategori}</b>
</div>
<ul>
{cat.items.map((item) => (
<li>{item.jenis}</li>
))}
</ul>
</>
))}
</div>
);

Resources