I have a function which gets the user input and update the array if the same key is available already. with the help of this article
This is how it looks;
const handleClickYes = (question) => {
// find if question is in the data array
const hasQuestion = data.find(({ parentId }) => question.id === parentId)
const indexOfQuestion = data.indexOf(hasQuestion)
if (hasQuestion) {
// update the value with specific selected index in the array.
data[indexOfQuestion] = { question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }
} else {
setData((data) => data.concat({ question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }))
}
localStorage.setItem('deviceReport', JSON.stringify(data))
}
I'm using localStorage to persist the state
const deviceReport = localStorage.getItem('deviceReport') ? JSON.parse(localStorage.getItem('deviceReport')) : []
const [data, setData] = useState(deviceReport)
Here the problem is if I use setData then it updates instantly but on replacing the array
at this part
data[indexOfQuestion] = { question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }
it dosent update the mapped data on JSX portion. How can I configure it to update it happen in setState. ? Or any other better option to update the array.
You're not calling setState() within the first half of your if block. Also, never mutate state directly. Make a mutable copy, like so:
const handleClickYes = (question) => {
// find if question is in the data array
const hasQuestion = data.find(({ parentId }) => question.id === parentId);
const indexOfQuestion = data.indexOf(hasQuestion);
// copy data to mutable object
let newData = [...data];
if (hasQuestion) {
// update the value with specific selected index in the array.
newData[indexOfQuestion] = {
question: question.if_yes,
parentId: question.id,
userChoice: "YES",
child: [],
};
} else {
// concat existing data with a new question
newData = [
...newData,
{
question: question.if_yes,
parentId: question.id,
userChoice: "YES",
child: [],
},
];
}
localStorage.setItem("deviceReport", JSON.stringify(newData));
setData(newData);
};
Related
I'm trying to save objects to an array, but I can't do it, the old state is deleted. I have two states in my component, from two different forms, the first form is just text and I get the data by "handleChange", but the second form is several objects that I want to store in an array that I get by "handleChangeArray".
const [formCompra, setFormCompra] = useState({
name: '',
lastName: '',
items: []
});
const [restForm, setRestForm] = useState();
const handleChage = (e) => {
const { name, value } = e.target;
setFormCompra({
...formCompra,
[name]: value
})
}
const handleChangeArray = (e) => {
const { name, value } = e.target;
setRestForm({
...restForm,
[name]: value
})
}
const handleSubmit = () => {
let newData = {
name: formCompra.name,
lastName: formCompra.lastName,
items: [...formCompra.items, restForm] //probably the error is here
}
console.log(newData)
}
As I mention, it is not possible to save the data in the array, I appreciate any help.
You can use the current state to set a new value, keeping all other values:
setState((current) => ({
...current,
key: newValue
}));
I think the issue may be that spread syntax only shallow copies the array, so in
const handleSubmit = () => {
let newData = {
name: formCompra.name,
lastName: formCompra.lastName,
items: [...formCompra.items, restForm] //probably the error is here
}
items is a copy of an array that points to all the original objects.
try
let newData = {
name: formCompra.name,
lastName: formCompra.lastName,
items: [...formCompra.map(x=>{...x}), {...restForm}] //probably the error is here
}
this is my code
const [state, setState] = useState(
[{id: 1, key:""}, {id: 2, key:""}, {id: 3, key:""}]
)
i want to to change "key" state
im confuse
now im using
setState(
[...state].map((data, index) => {
if (data.id === state[index].id) {
return {
...data,
key: result,
};
} else return data;
}),
);
}
result variable came from result when i fetching data.
result is a random string
If your data structure is always going to be in that order data.id === state[index].id doesn't really achieve much.
For example:
when data.id is 1 the index will be 0. And state[0].id is 1.
when data.id is 2 the index will be 2. And state[1].id is 2.
etc.
It just sounds like you want to iterate over all the objects in state and update each key value with that random string you mentioned in the comment section. There's no need to make a copy of state since map already returns a new array ready for setState to use.
function setState(mapped) {
console.log(mapped);
}
const state = [{ id: 1, key: '' }, { id: 2, key: '' }, { id: 3, key: '' }];
const result = 'random';
const mapped = state.map(data => {
return { ...data, key: result };
});
setState(mapped);
I followed the approach as the answer in this question suggested
The issue is that I want to construct an Array using setState and I dont; want to add duplicate data.
here is the sample data
const data = [
{
parentId: '1',
userChoice: 'NO',
child: []
},
{
parentId: '2',
userChoice: 'NO',
child: []
},
}
I'm catching the parentId from question.id from user input. If there is the same question then I don't want to concat into the array.
This is how I'm trying.
const [data, setData] = useState([]) // state
function arrayHandler(question) {
const hasParentId = data.find((parentId) => question.id === parentId)
// concat if array do not have any question with same id.
if (!hasParentId) {
setData((data) => data.concat({ parentId: question.id, userChoice: 'NO', child: [] }))
}
}
But this is not working, How can I fix this ?
You can check if any of the elements in the data have a matching ID using Array.some and if not then you can use concat or just the spread operator to add the new object to the existing data.
function arrayHandler(question) {
if (!data.some((d) => question.id === d.parentId)) {
setData((data) => [...data, { parentId: question.id, userChoice: "NO", child: [] }]);
}
}
I think that now it shold work
function arrayHandler(question) {
const hasParentId = data.find((object) => question.id === object.parentId)
// concat if array do not have any question with same id.
if (!hasParentId) {
setData((data) => data.concat({ parentId: question.id, userChoice: 'NO', child: [] }))
}
}
I've got an object of type : [ {name : 'xxx' , price: '555', quantity : '2' } , {...} ] and so one.
I got a class
getCartItems() {
let items = localStorage.getItem('item');
items = JSON.parse(items);
return items;
}
where i get this array.
Now i am getting index of the array, for example 0 , it should remove first array from object.
but when i do .remove, or other, it does not work. this.getCartItems()[index].remove or other does not work. Can you help me?
My guess is that you are mutating the object after you parse it and you never save it back.
You have to save the mutated object inside of your localStorage to make your removal of the first item persistant.
Look at the following example :
const localStorage = {
items: {
item: JSON.stringify([{
name: 'xxx',
price: '555',
quantity: '2',
}, {
name: 'yyy',
price: '666',
quantity: '5',
}, {
name: 'zzz',
price: '777',
quantity: '6',
}]),
},
getItem: str => localStorage.items[str],
setItem: (str, value) => {
localStorage.items[str] = value;
},
};
function getCartItems() {
const items = localStorage.getItem('item');
const parsedItems = JSON.parse(items);
// We remove the first element
const item = parsedItems.splice(0, 1);
// We save the value
localStorage.setItem('item', JSON.stringify(parsedItems));
return item;
}
console.log('First call ---');
console.log(getCartItems());
console.log('');
console.log('Second call ---');
console.log(getCartItems());
console.log('');
console.log('Third call ---');
console.log(getCartItems());
Use filter to get required items. In the following updated will not have earlier 0 index item. Now, the updated array you may want to set in localStorage again if required.
const items = getCartItems();
const indexToRemove = 0;
const updated = items.filter((,index) => index !== indexToRemove);
You can use array method filter to remove the object from array. This can look something like this:
getCartItems() {
let items = localStorage.getItem('item');
items = JSON.parse(items);
return items;
}
removeCart(){
return id; // the id that you will have from your a tag
}
const updatedItems = this.getCartItems().filter((item,index) => index !== this.removeCart()); // in updated items you will find your filtered out array of object
In my post request I need to pass an array with an object inside it.
when I tried to add new properties inside an object its adding.
but when I tried to add when an object is present inside an array its not adding.
I have sportsvalues as array const sportsValues = [{ ...values }];
I am trying to build something like this, so that I can pass in the api
[
{
"playerName": 3,
"playerHeight": 1
}
]
can you tell me how to fix it.
providing my code snippet below.
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
console.log("sportsValues--->", sportsValues);
// sportsValues.playerName = 3//'';
// sportsValues.playerHeight = 1//'';
console.log("after addition sportsValues--->", sportsValues);
console.log("after deletion sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}
Since sportsValues is an array of objects, you can push new object into it. Check out code below.
const sportsValues = [];
sportsValues.push({
playerName:'3',
playerHeight: 1,
});
console.log(sportsValues);
I don't fully understand what you're trying to do, but here's some pointers:
If you're trying to update the object that's inside the array, you first have to select the object inside the array, then update it's attribute:
sportsValues[0].playerName = 3
although, I recommend building the object correctly first, then passing it to the array, it makes it a little easier to understand in my opinion:
const sportsValues = [];
const firstValue = { ...values };
firstValue.playerName = '3';
sportsValues.push(firstValue);
or
const firstValue = { ...values };
firstValue.playerName = '3';
const sportsValues = [firstValue];
or
const sportsValues = [{
...values,
playername: '3',
}];
if you're trying to add a new object to the array, you can do this:
const sportsValues = [{ ...values }];
sportsValues.push({ playerName: '3' });
etc...
Array.push adds a new item to the array, so in your code, you're going to have 2 items because you assign 1 item at the beginning and then push a new item:
const ar = [];
// []
ar.push('item');
// ['item']
ar.push({ text: 'item 2' });
// ['item', { text: 'item 2' }]
etc...
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
let playerName='3'
sportsValues.playerName= playerName; // you can bind in this way
console.log("sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}