how to access a particular object element in array - reactjs

I have used a map function to using reduce and I got an array of objects.
How can I get a particular value in the "return"?
Below is the console output
{design job: Array(2)}
design job: Array(2)
0:
fullName: "Rakesh"
phoneno: "1111111111"
__proto__: Object
1:
fullName: "test user"
phoneno: "9176837787"
__proto__: Object
length: 2
__proto__: Array(0)
__proto__: Object
Below is my code
const list = appliedCandidates.reduce(
(appliedCandidate, { Title, fullName, phoneno }) => {
(appliedCandidate[Title] = appliedCandidate[Title] || []).push({
fullName: fullName,
phoneno: phoneno
});
return appliedCandidate;
},
{}
);
console.log(list);
return (
<div>
{Object.keys(list).map((item, i) => {
return (
<ul>
{item}
<li key={i}>{item.fullName}</li>
</ul>
);
})}
</div>
);

Assuming your data looks like this:
const jobs = {
"design job": [
{
fullName: "Rakesh",
phoneno: "1111111111"
},
{
fullName: "test user",
phoneno: "9176837787"
}
],
"another job": [
{
fullName: "Rakesh",
phoneno: "1111111111"
},
{
fullName: "test user 2",
phoneno: "9176837787"
}
]
};
Here's the code that returns the JSX to display all the jobs, and for each job, all the candidates:
return Object.entries(jobs).map(([title, candidates]) => (
<ul>
<h3>{title}</h3>
{candidates.map((c, i) => (
<li key={i}>{c.fullName}</li>
))}
</ul>
));

function iMGroot() {
let appliedCandidates = [{
Title: 'title-1',
fullName: 'fullName-1',
phoneno: 'phoneno-1'
},
{
Title: 'title-11',
fullName: 'fullName-11',
phoneno: 'phoneno-11'
},
{
Title: 'title-12',
fullName: 'fullName-12',
phoneno: 'phoneno-12'
},
{
Title: 'title-13',
fullName: 'fullName-13',
phoneno: 'phoneno-13'
}, {
Title: 'title-14',
fullName: 'fullName-14',
phoneno: 'phoneno-14'
}
]
const list = appliedCandidates.reduce(
(appliedCandidate, {
Title,
fullName,
phoneno
}) => {
(appliedCandidate[Title] = appliedCandidate[Title] || []).push({
fullName: fullName,
phoneno: phoneno
});
return appliedCandidate;
}, {}
);
console.log(list);
return ( `<div> ${Object.keys(list).map((item, i) => {
return (
`<ul>
${list[item].map(lItem=>{
return `
<li>${lItem.fullName}</li>
<li>${lItem.phoneno}</li>
`
})}
</ul>`
)
})}</div>`
);
}
console.log(iMGroot())
PS: see the return statement of function iMGroot.
Since definition of appliedCandidates is missing, I've filled it in the above function.

Related

Storybook component not show

I setup Storybook to my project and add stories to my components. In simple components like button or Input stories appear in storybook. When i am creating stories on more advance component i cant see this component in stories. In stories i dont have any errors and i pass all args to component in story. My component looks like this:
return (
<Box>
<Paper>
{projects.map((project) => {
return project.timetracking.map((value) => {
switch (project.strategy) {
case StrategyEnum.HoursMonthly:
return (
<HoursMonthly comment={value.comment} date={value.date} hours={value.hours} />
);
case StrategyEnum.HoursDaily:
return <HoursDaily comment={value.comment} date={value.date} hours={value.hours} />;
case StrategyEnum.HoursPerTask:
return (
<HoursPerTask
comment={value.comment}
date={value.date}
hours={value.hours}
taskUrl={value.taskUrl}
/>
);
default:
return <Text>No strategy match</Text>;
}
});
})}
</Paper>
</Box>
);
};
export default TimetrackingRecords;
I write a story to this component and my story look like this:
title: 'timetracking/Records',
component: TimetrackingRecords,
} as Meta;
const Template: Story<Organization> = (args) => <TimetrackingRecords {...args} />;
export const Monthly = Template.bind({});
Monthly.args = {
id: '12jk4l12kj412rjl12jrkeqwpk',
name: 'Organizacja 1',
description: 'Nice oragnization 3, very nice',
projects: [
{
id: 'qwklkrqwlqkrlqkrw',
name: 'Project 1',
users: [
{ id: 'fdfasfasfs', email: 'test2#test.com', firstName: 'Jan', lastName: 'Kowalski' },
],
strategy: StrategyEnum.HoursMonthly,
timetracking: [
{
id: '5545dasdas54564',
hours: 3,
date: '12/12/2022',
comment: 'simple comment',
taskUrl: 'https://bebit.atlassian.net/browse/TIM-11',
},
],
},
],
users: [{ id: 'qwrlqwjrkwqjrlvn', email: 'test#test.com', firstName: 'John', lastName: 'Doe' }],
};
What i am doing wrong? Story not showing any errors. Maybe i have something wrong with configuration or Component.

How i render checkboxes with nested array of objects

I have a checkbox component which renders multiple day checkboxes. I need to print the values of the selected checkboxes. The sample given below looks like the one:
const [state, setState] = useState({
"firstName": "",
"lastName" : "",
"mobileNumber" : "",
"avalabilities": [{"availabilityId": "",
day: [
{
value: "sun",
name: "Sunday"
},
{
value: "mon",
name: "Monday"
},
{
value: "tue",
name: "Tuesday"
},
{
value: "wed",
name: "Wednesday"
},
{
value: "thur",
name: "Thursday"
},
{
value: "fri",
name: "Friday"
},
{
value: "sat",
name: "Saturday"
}
],
"isChecked": false,
"checked" : false,
"allChecked": false,
"error": null});
this is the console value given below
{firstName: '', lastName: '', mobileNumber: '', avalabilities: Array(1), …}
allChecked: false
avalabilities: Array(1)
0:
availabilityId: ""
day: (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]
[[Prototype]]: Object
length: 1
[[Prototype]]: Array(0)
close: false
disabled: false
error: null
firstName: ""
isChecked: false
isPending: false
lastName: ""
mobileNumber: ""
open: false
this is how I am trying to render the arrays
{(avalabilities || [{}]).map((av, index) => {
return (
<div key={av.availabilityId}>
<>
{av.day.map((item) => {
return (
<div>
<input
checked={item.checked || false}
onChange={() => handleChange3(item.value)}
type="checkbox"
/>
</div>
);
})}
</>
But the error on mapping with day array is coming below like this
are not valid as a React child (found: object with keys {value, name}). If you meant to render a collection of children, use an array instead.
const checkedHandler = (event) => {
setState(...)
//Well, here I don't know how change the particular value of the
array...}
Any help is highly appreciated.
If i'm correct you want to show values of each checkbox and save the respective checkbox value when we toggle any checkbox.
You have avalabilities array & in each object we have another day array. I render the all the avalabilities. Now when i toggle any checkbox, i pass three things to checkHandler:
e which is native event of checkbox
avIndex which is index of object in avalabilities array
index which is index of object in day array.
Now each day object, i set a key checked and store the value of that checkbox by getting the value from e.target.checked.
Hope this solve your problem
newState.avalabilities[avIndex].day[index].checked = e.target.checked;
import { useState } from 'react';
export default function App() {
const [state, setState] = useState({
firstName: '',
lastName: '',
mobileNumber: '',
avalabilities: [
{
availabilityId: '',
day: [
{ value: 'sun', name: 'Sunday' },
{ value: 'mon', name: 'Monday' },
{ value: 'tue', name: 'Tuesday' },
{ value: 'wed', name: 'Wednesday' },
{ value: 'thur', name: 'Thursday' },
{ value: 'fri', name: 'Friday' },
{ value: 'sat', name: 'Saturday' }
],
isChecked: false,
checked: false,
allChecked: false,
error: null
}
]
});
const checkedHandler = (e, avIndex, index) => {
console.log(e.target.checked, avIndex, index);
setState((prev) => {
let newState = { ...prev };
newState.avalabilities[avIndex].day[index].checked = e.target.checked;
return newState;
});
};
return (
<>
{state.avalabilities.map((av, avIndex) => (
<div key={av.availabilityId}>
{av.day.map((item, index) => (
<div key={index}>
<input
checked={item?.checked || false}
onChange={(e) => checkedHandler(e, avIndex, index)}
type='checkbox'
/>
<span>{item.name}</span>
</div>
))}
</div>
))}
</>
);
}

Select form field not populating with options from state in ReactJS

This is my select function
import React from "react";
const Select = ({ name, label, options, error, ...rest }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<select {...rest} id={name} name={name} className="form-control">
<option value="" />
{options.map((option) => (
<option key={option.id} value={option.id}>
{option.name}
</option>
))}
</select>
{error && <div className="alert alert-danger">{error}</div>}
</div>
);
};
export default Select;
This is the component state
state = {
data: {
vat: "",
city: "",
country: "",
mobile_number: "",
address: "",
has_conference: false,
star_rating: "",
},
errors: {},
hotel_type: [],
};
This function to populate data in the hotel_type
populateHotel_Types = () => {
let hotel_type = [...this.state.hotel_type];
hotel_type = [
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
And Finally this is the render function
{this.renderSelect(
"hotel_type",
"Hotel Type",
this.state.hotel_type
)}
Render select function
renderSelect(name, label, options) {
const { data, errors } = this.state;
return (
<Select
options={options}
name={name}
value={data[name]}
label={label}
onChange={this.handleChange}
error={errors[name]}
/>
);
}
Now i am struggling to get the data populated in the renderselect function. I am quite new to react and i am actually assuming this might be a silly question therefore kindly bear with me. What could be wrong with this code. Please help. Thanks
I think in first place, you have a problem here:
populateHotel_Types = () => {
let hotel_type = [...this.state.hotel_type];
hotel_type = [
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
Here, you are filling hotel_type with your state. And below, you are redefining the array, so you will have just this 3 new objects. So should do this to have the full list:
populateHotel_Types = () => {
const hotel_type = [
...this.state.hotel_type,
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
I suspected this was a silly question and indeed it was. I was forgetting to run the function populateHotel_Types in the componentDidMount function. Therefore the state was not being updated appropriately. I am leaving this here so that any newbie like myself will get an answer to such a scenario

TypeError: posts is not iterable returning data from firebase

I'm new using react and firebase.
I try to get posts from firebase:
useEffect(() => {
setLoading(true);
setError(false);
let cancel;
// get posts
var postsRef = firebase.database().ref('/posts/');
postsRef.on('value', function(snapshot) {
setPosts(prevPosts => {
var posts = snapshot.val();
console.log(posts);
return [...prevPosts,...posts]
});
});
setLoading(false);
}, [ pageNumber ]);
The problem is it gives me:
TypeError: posts is not iterable on return [...prevPosts,...posts]
any ideas how to solve this? this will return data to a function that will parse data like this:
return (
<>
{posts.map((post, index) => {
return <Post key={post.id} id={post.id} ref={ref} img={post.img} titulo={post.titulo} />
})}
</>
)
Why I get this error? how can I parse my data correctly?
thanks!
Since your post variable is an object like:
{
"-M5GmoelPzWryNizVjww": { img: "img/", titulo: "title 1", user: "root" },
"-M5GmsTDcbDYZuoYBVIt": { img: "img/", titulo: "title 2", user: "root" },
"-M5GmxMZMzZe9p5uDuWe": { img: "img/", titulo: "title 3", user: "root" },
"-M5GmyKDbbtxR8Dw3-J2": { img: "img/", titulo: "title 4", user: "root" },
"-M5GmzHjK1PQJ2ulrCTi": { img: "img/", titulo: "title 5", user: "root" },
"-M5Gn2Rsv_OrwL1GkbVG": { img: "img/", titulo: "title 6", user: "user" },
"-M5Gn39y9JDishOdxwi4": { img: "img/", titulo: "title 7", user: "user" }
}
You should transform it previously to an array so that you can concatenate it to your previous list of posts. To do so, and using the key of the object as an id, you can use:
return [...prevPosts, ...Object.keys(posts).map(key => ({
id: key,
...posts[key]
}))];

Update state using nested map es6

My state has an array of objects that also contains an array of objects.
var state = {
prop1: null,
categories: [
{
categoryId: 1,
tags: [
{
tagId: 1,
name: 'AA11',
status: true,
},
{
tagId: 2,
name: 'AA22',
status: false,
}
]
},
{
categoryId: 2,
tags: [
{
tagId: 1,
name: 'BB11',
status: true,
},
{
tagId: 2,
name: 'BB22',
status: false, // let's say i want to toggle this
}
]
},
]
};
I have an action that will toggle a status of a tag. This action will receive parameters categoryId and tagId.
So far I've come up with this but it doesn't work
return {
...state,
categories: state.categories.map((category) => {
category.tags.map(tag => (
(tag.tagId === action.tagId && category.categoryId === action.categoryId) ? {
...tag,
status: !tag.status,
} : tag));
return category;
}),
};
I finally fixed the map code.
return {
...state,
categories: state.categories.map(category => ((category.id === action.categoryId) ?
{
...category,
tags: category.tags.map(tag => (tag.id === action.tagId ? {
...tag, status: !tag.status,
} : tag)),
} : category)),
};

Resources