Unable update the nested state - javascript

I am trying to update the state, but the state is not getting updated as expected. Partially gets updated.
I need help in updating the updatedData data.
My state is as below.
this.state = {
userData: {
accounts: { '82345': 'Data 1' },
jobTitle: { '79438': 'Data 2' },
state: { '82099': 'Data 3' },
country: { '82008': 'Data 4' },
},
updatedData: {
firstName: ‘Parul’,
lastName: ‘Rathod’,
mail: parulRathod#gmail.com,
accounts: '',
jobTitle: '',
state: '',
country: '',
},
};
}
I need the data to be saved as
accounts: { label: 'Data 1', value: '82345' },
jobTitle: { label: 'Data 2', value: '79438' },
state: { label: 'Data 3', value: '82099' },
country: { label: 'Data 4', value: '82008' },
I have tried using the below method to do the required steps, but only country gets updated, and the rest remains as the previous state.
setUserData = () => {
for (const key of Object.keys(this.state.userData)) {
if(typeof (this.state.userData[key]) === 'object') {
const seperator = this.state.userData[key];
if(seperator) {
const values = Object.values(seperator);
const keys = Object.keys(seperator);
const data = { label: values[0], value: keys[0] };
if (key === 'country') {
this.setState({
updatedData: {
...this.state.updatedData,
country: data,
},
});
} else if (key === 'accounts') {
this.setState({
updatedData: {
...this.state.updatedData,
accounts: data,
},
});
} else if (key === 'state') {
this.setState({
updatedData: {
...this.state.updatedData,
state: data,
},
});
} else if (key === 'jobTitle') {
this.setState({
updatedData: {
...this.state.updatedData,
jobTitle: data,
},
});
}
}
}
}
}

Related

How to construct an array of object to unique array of object

I have an array of object like this
let data =
[
{
text: 'label'
},
{
text: 'username'
},
{
text: 'category'
},
{
text: 'book'
},
{
text: 'john'
},
{
text: 'education'
},
{
text: 'car'
},
{
text: 'doe'
},
{
text: 'automotive'
},
{
text: 'shoes'
},
{
text: 'cena'
},
{
text: 'fashion'
},
]
and my expect array of objects
let result =
[
{
label: 'book',
username: 'john',
category: 'education'
},
{
label: 'car',
username: 'doe',
category: 'automotive'
},
{
label: 'shoes',
username: 'cena',
category: 'fashion'
},
]
Just a simple for loop is probably the clearest. Here storing each object in a temp variable to avoid having to access the end of the result array every iteration, and abstracting the size into a variable.
let data = [{ text: 'label' }, { text: 'username' }, { text: 'category' }, { text: 'book' }, { text: 'john' }, { text: 'education' }, { text: 'car' }, { text: 'doe' }, { text: 'automotive' }, { text: 'shoes' }, { text: 'cena' }, { text: 'fashion' },];
const size = 3;
const result = [];
for (let temp, i = size; i < data.length; i++) {
if (i % size === 0) {
result.push(temp = {});
}
temp[data[i % size].text] = data[i].text;
}
console.log(result)
How about a switch-case with a modulo % operator to check for the current key:
const transformData = (data) => {
let result = [];
let tmpObj = {};
data.forEach((element, idx) => {
switch (idx % 3) {
case 0:
tmpObj["label"] = element.text;
break;
case 1:
tmpObj["username"] = element.text;
break;
case 2:
result.push({ ...tmpObj,
category: element.text
});
tmpObj = {};
break;
default:
break;
}
});
return result;
};
console.log(transformData(getSampleData()));
function getSampleData() {
return [{
text: 'label'
},
{
text: 'username'
},
{
text: 'category'
},
{
text: 'book'
},
{
text: 'john'
},
{
text: 'education'
},
{
text: 'car'
},
{
text: 'doe'
},
{
text: 'automotive'
},
{
text: 'shoes'
},
{
text: 'cena'
},
{
text: 'fashion'
},
];
}
According to your data,the top 3 records are property name,others are data,so we can use Array.slice() to get the property names
Then we can use Array.reduce() to convert the left data
let keys = data.slice(0,3).map(v => v.text)
let result = data.slice(3).reduce((a,c,i) =>{
let key = keys[i%3]
if(i%keys.length ==0){
let obj = {}
obj[key] = c.text
a.push(obj)
}else{
a.at(-1)[key]=c.text
}
return a
},[])
console.log(result)
let data =
[
{
text: 'label'
},
{
text: 'username'
},
{
text: 'category'
},
{
text: 'book'
},
{
text: 'john'
},
{
text: 'education'
},
{
text: 'car'
},
{
text: 'doe'
},
{
text: 'automotive'
},
{
text: 'shoes'
},
{
text: 'cena'
},
{
text: 'fashion'
},
]
let keys = Object.values(data.slice(0,3)).map(v => v.text)
let result = data.slice(3).reduce((a,c,i) =>{
let key = keys[i%3]
if(i%keys.length ==0){
let obj = {}
obj[key] = c.text
a.push(obj)
}else{
a.at(-1)[key]=c.text
}
return a
},[])
console.log(result)

filter an array with a button in React

so I'm making a filtered list app where you can click on the buttons and it excludes all users with that letter in its name. This is what I have so far, but it doesn't work for me. Any help would be appreciated.
Also I keep getting this error ./src/index.js and its bringing up these error
App.js
import React from 'react';
import "./App.css";
const buttons = [
{ name: "Reset", value: "Reset"},
{ name: "Bryan", value: "B"},
{ name: "Annie", value: "A"},
{ name: "Miles", value: "M"},
];
class User extends React.Component {
constructor() {
super();
this.state = {
users: [
{
name: "Bam",
},
{
name: "Brinley",
},
{
name: "Bart",
},
{
name: "Brielle",
},
{
name: "Booka",
},
{
name: "Ann",
},
{
name: "Analise",
},
{
name: "Anthony",
},
{
name: "Arrow",
},
{
name: "Arika",
},
{
name: "Marty",
},
{
name: "Mike",
},
{
name: "Minto",
},
{
name: "Milk",
},
{
name: "Monty",
},
{
name: "Brett",
},
{
name: "Byron",
},
{
name: "Brad",
},
{
name: "Bento",
},
{
name: "Bark",
},
]
filterName: []
};
}
componentDidMount() {
this.setState({
filterName: this.state.users
});
}
handleClick = name => {
let filterName = [];
if (name === "All") {
filterName = this.state.users;
} else {
filterName = this.state.users.filter(
users => users.origin === name
);
}
this.setState({ filterName });
};
render() {
const renderAll = this.state.filterName.map(User => (
<li key={User.name}>{users.name}</li>
));
return (
<div>
{buttons.map(({ name, value }) => (
<button
key={name}
value={value}
onClick={this.handleClick.bind(this, name)}
>
{name}
</button>
))}
<p>User: {renderAll}</p>
<h2>{this.state.filterName.length}</h2>
</div>
);
}
}
export default App;
You have missed a comma before filterName
//more on top
{
name: "Bark",
},
],
filterName: []
I have made the modification for your onClick function
handleClick = name => {
let filterName = []
const { users } = this.state;
if (name && name !== "All") {
filterName = users.filter(
//no such property called origin, only 'name' occurs. Therefore, I assume that you mean you want to use name as the sorting criteria
user => user.name === name
);
} else {
// For name === 'all' && name === undefined cases
filterName = users
}
this.setState({ filterName });
};
It's a syntax error, you missed a comma before filterName: [].

How to replace values in my array of objects using key from other object in another array

I have 2 arrays of objects
NOTE: status and original-language can't be set manually as they change all the time, these are custom fields. The slugs from fields make up all custom fields.
const items = [
{
name: 'Surviving the Game',
status: 'ffdb29ba075fcbc0b71295c31a13d64f',
original-language: 'b4ebbe06702794d1cf375274197267b2',
},
{
name: 'Some Movie',
status: 'cd53c082c6ca9e7d3ec66890e66c01f3',
original-language: '7a1cac74217747933bb3915888dea090',
},
];
const fields = [
{
slug: 'status',
options: [
{
name: 'Released',
id: 'ffdb29ba075fcbc0b71295c31a13d64f',
},
{
name: 'Upcoming',
id: 'cd53c082c6ca9e7d3ec66890e66c01f3',
},
],
},
{
slug: 'original-language',
options: [
{
name: 'de',
id: 'b4ebbe06702794d1cf375274197267b2',
},
{
name: 'en',
id: '7a1cac74217747933bb3915888dea090',
},
],
},
];
status and original-language in [items] have an id value which matches an option in the corresponding fields array.
I am trying to return a new array for [items] with the name from options with the matching id.
eg:
[
{
name: 'Surviving the Game',
status: 'Released',
original-language: 'de',
},
{
name: 'Some Movie',
status: 'Upcoming',
original-language: 'en',
},
];
How would I go about this with ES6/7?
I am not sure where to start
I would accomplish this by creating a lookup object that houses lookups for both your statuses and languages. You can then use this lookup object when mapping through your items.
var items = [
{
name: 'Surviving the Game',
status: 'ffdb29ba075fcbc0b71295c31a13d64f',
"original-language": 'b4ebbe06702794d1cf375274197267b2'
},
{
name: 'Some Movie',
status: 'cd53c082c6ca9e7d3ec66890e66c01f3',
"original-language": '7a1cac74217747933bb3915888dea090'
}
];
var fields = [
{
slug: 'status',
options: [
{
name: 'Released',
id: 'ffdb29ba075fcbc0b71295c31a13d64f'
},
{
name: 'Upcoming',
id: 'cd53c082c6ca9e7d3ec66890e66c01f3'
}
]
},
{
slug: 'original-language',
options: [
{
name: 'de',
id: 'b4ebbe06702794d1cf375274197267b2'
},
{
name: 'en',
id: '7a1cac74217747933bb3915888dea090'
}
]
}
];
const lookup = {};
fields.forEach(field => {
lookup[field.slug] = field.options.reduce((all, option) => ({
...all,
[option.id]: option.name
}), {})
});
const translatedItems = items.map(item => {
return Object.entries(item)
.reduce((all, [key, val]) => ({
...all,
[key]: lookup[key] ? lookup[key][val] : val
}),{});
});
console.log(translatedItems);
I'd define a function that obtains the value for a field, like so:
function valueForField(field, id) {
const field = fields.find((itemfields) => itemfields.slug === field);
if(!field) return null;
const option = field.options.find(option => option.id === id);
if(!option) return null;
return option.name;
}
This can then be used like so:
const newItems = items.map(item => {
const { name } = item;
const newItem = {name};
newItem["original-language"] = valueForField('original-language', item["original-language"]);
newItem.status = valueForField('status', item.status);
return newItem;
});
Use map to create a new array of objects having name, status and originalLanguage fields along with the find method to get the name from fields for every status identifier.
const items = [{
name: 'Surviving the Game',
status: 'ffdb29ba075fcbc0b71295c31a13d64f',
originalLanguage: 'b4ebbe06702794d1cf375274197267b2',
},
{
name: 'Some Movie',
status: 'cd53c082c6ca9e7d3ec66890e66c01f3',
originalLanguage: '7a1cac74217747933bb3915888dea090',
},
];
const fields = [{
slug: 'status',
options: [{
name: 'Released',
id: 'ffdb29ba075fcbc0b71295c31a13d64f',
},
{
name: 'Upcoming',
id: 'cd53c082c6ca9e7d3ec66890e66c01f3',
},
],
},
{
slug: 'original-language',
options: [{
name: 'de',
id: 'b4ebbe06702794d1cf375274197267b2',
},
{
name: 'en',
id: '7a1cac74217747933bb3915888dea090',
},
],
},
],
newArr = items.map(i => ({
name: i.name,
status: fields.find(f => f.slug == 'status').options.find(o => o.id == i.status).name,
originalLanguage: fields.find(f => f.slug == 'original-language').options.find(l => l.id == i.originalLanguage).name
}));
console.log(newArr);

UUIDV4 in for loop not changing value

I am trying to create a function to generate an array of objects with a UUID as the key, as well as a UUID for some of the nested object ids.
Each game will be based on a mock object which I import into the file.
The function expects a sport (string) which will get assigned to a key and a quantity (number) which will determine the for loop iterations.
When using a for loop the UUID for the nested object ids are getting overridden on each iteration.
const mockGame = require('../mock-game');
const uuidv4 = require('uuid/v4');
function generateMockGames(sport, quantity) {
let games = []
for (let i = 0; i < quantity; i++) {
let game = {}
let id = uuidv4()
game[id] = {
search: mockGame.search,
query: mockGame.query,
variables: mockGame.variables,
}
game[id].search.eventId = id
game[id].search.competition.categoryName = sport
game[id].search.id = id
game[id].search.competition.categoryName = sport;
games.push(game);
}
return games;
}
const mockFootballGame = generateMockGames('football', 3);
Expected result:
[
{
'286c1911-b155-4197-bbde-64dba0b304fe': {
search: {
eventId: '286c1911-b155-4197-bbde-64dba0b304fe',
name: 'test name',
competition: {
categoryName: 'football'
}
},
query: {
id: '286c1911-b155-4197-bbde-64dba0b304fe',
competition: {
categoryName: 'football'
}
},
variables: {
name: 'test name'
}
},
{
'082a46a6-4dde-433d-8011-9e94a5ee79ff': {
search: {
eventId: '082a46a6-4dde-433d-8011-9e94a5ee79ff',
name: 'test name',
competition: {
categoryName: 'football'
}
},
query: {
id: '082a46a6-4dde-433d-8011-9e94a5ee79ff',
competition: {
categoryName: 'football'
}
},
variables: {
name: 'test name'
}
},
{
'ba911751-3ea3-40ab-9bec-c525ab2a07b9': {
search: {
eventId: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
name: 'test name',
competition: {
categoryName: 'football'
}
},
query: {
id: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
competition: {
categoryName: 'football'
}
},
variables: {
name: 'test name'
}
}
]
Output is:
[
{
'286c1911-b155-4197-bbde-64dba0b304fe': {
search: {
eventId: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
name: 'test name',
competition: {
categoryName: 'football'
}
},
query: {
id: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
competition: {
categoryName: 'football'
}
},
variables: {
name: 'test name'
}
},
{
'082a46a6-4dde-433d-8011-9e94a5ee79ff': {
search: {
eventId: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
name: 'test name',
competition: {
categoryName: 'football'
}
},
query: {
id: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
competition: {
categoryName: 'football'
}
},
variables: {
name: 'test name'
}
},
{
'ba911751-3ea3-40ab-9bec-c525ab2a07b9': {
search: {
eventId: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
name: 'test name',
competition: {
categoryName: 'football'
}
},
query: {
id: 'ba911751-3ea3-40ab-9bec-c525ab2a07b9',
competition: {
categoryName: 'football'
}
},
variables: {
name: 'test name'
}
}
]
You are assigning subobjects of mockGame in your loop to the entries, without copying them. So you keep overwriting mockGame.query.id etc, with a new uuid in your loop, but then assign the mockGame.query object as a whole to your output.

Object.assign make duplicate when post a request

I create a ticket using zendesk but I didn't know why this happens
here is node js code:
config.js
baseTicketObject: {
'comment': {
'body': null,
},
'requester': {
'name': null,
'email': null,
},
'custom_fields': [],
},
create ticket api
function createTicketObjectFromRequest(req) {
const requestBody = req.body;
console.log('requestBody', requestBody);
console.log('config.baseTicketObject', config.baseTicketObject);
const ticket = Object.assign(config.baseTicketObject, {});
//console.log('ticket', ticket);
const {
messageBody, email, name, customFields,
} = requestBody;
//console.log('ticket.custom_fields', ticket.custom_fields);
// Request must contain a name, email and body
ticket.requester.name = name;
ticket.requester.email = email;
ticket.comment.body = messageBody;
if (req.user && req.user.id) {
ticket.custom_fields.push(createCustomFieldObject(config.customFieldNameToZendeskFieldIdMapping['userId'], Number(req.user.id)));
}
Object.keys(config.customFieldNameToZendeskFieldIdMapping).forEach((fieldName) => {
if (config.customFieldNameToZendeskFieldIdMapping[fieldName] === config.customFieldNameToZendeskFieldIdMapping.userId) {
return;
}
//console.log('fieldName', fieldName);
const mappedCustomFieldId = config.customFieldNameToZendeskFieldIdMapping[fieldName];
if (mappedCustomFieldId) {
ticket.custom_fields.push(createCustomFieldObject(mappedCustomFieldId, !customFields[fieldName] ? '' : customFields[fieldName]));
}
});
return { ticket: ticket };
}
whenever I post a request the config.baseTicketObject will keep all items i pushed before like this
config.baseTicketObject { comment: { body: null },
requester: { name: null, email: null },
custom_fields: [] }
-------------------------------------
config.baseTicketObject { comment: { body: 'dgfhdgfhdgfh dgfhdfghdfg' },
requester: { name: 'test other', email: 'tranthiphuonghue96#yopmail.com' },
custom_fields:
[ { id: 360010481051, value: '' },
{ id: 360010510411, value: '' },
{ id: 360010406792, value: '' },
{ id: 360010511011, value: '' },
{ id: 360010511191, value: '' },
{ id: 360010920852, value: 'contact_support' } ] }
---------------------------------------------------------
config.baseTicketObject { comment: { body: 'dgfhdgfhdgfh dgfhdfghdfg' },
requester: { name: 'test other', email: 'tranthiphuonghue96#yopmail.com' },
custom_fields:
[ { id: 360010481051, value: '' },
{ id: 360010510411, value: '' },
{ id: 360010406792, value: '' },
{ id: 360010511011, value: '' },
{ id: 360010511191, value: '' },
{ id: 360010920852, value: 'contact_support' },
{ id: 360010481051, value: '' },
{ id: 360010510411, value: '' },
{ id: 360010406792, value: '' },
{ id: 360010511011, value: '' },
{ id: 360010511191, value: '' },
{ id: 360010920852, value: 'contact_support' } ] }
I don't know why the config.baseTicketObject like that, please help.
Reverse parameters order in Object.assing.
You have
Object.assign(config.baseTicketObject, {});
but should be
Object.assign({}, config.baseTicketObject);
Object.assign syntax
Object.assign(target, ...sources)
In your case
const ticket = Object.assign({}, config.baseTicketObject);
Edit:
Add
ticket.custom_fields = [];
after
const ticket = Object.assign({}, config.baseTicketObject);
because Object.assign create shallow copy, witch mean that ticket.custom_fields still holds reference to original array object from config.baseTicketObject.custom_fields

Categories