React/JavaScript: Adding property to nested array in state in React - javascript

I need to add an id number to the nested array in data called action. The code I'm using is:
const { data } = this.state
const newData = Object.assign([...data.action], Object.assign([...data.action],{0:'id' }))
but this code is not working. The result I am looking for is:
{id:1 action: "user...}

You can just use the spread operator.
const newData = {
...data,
action: {
...data.action,
id: 1
}
};
If action is an array, you can try something like this:
const newAction = data.action.map((actionItem, index) => ({
...actionItem,
id: index + 1
}));
const newData = {
...data,
action: newAction
};

Related

the previous state is not saved - React useatate

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
}

Push objects into an array in reactjs

I'm getting a list of objects as a response like this
As you can see the objects are not in an array. I want to push these objects into an array. I tried the following way
this.setState({
countrydata: this.state.countrydata.push(datasnapshot.val()),
})
But it didn't work. What's the correct approach to push these objects into an array?
PS:
componentDidMount() {
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
firebaseHeadingref.once('value').then(datasnapshot => {
this.setState({
countrydata: datasnapshot.val(),
countryName: countryName,
loading: false
})
});
}
I think that the "countrydata" in a dict not an array.
Try to initialize the it as an empty array.
Array.prototype.push returns the new length of the array after the push, so you are essentially setting the state to a number.
You are not allowed to mutate the array with React state, you need to create a new array containing your new elements:
// When updating state based on current state, use the function form of setState.
this.setState(state => {
countrydata: [...state.countrydata, datasnapshot.val()],
})
This is assuming countryData is indeed an array, which from your screenshot, it appears to not (it seems to be an object), so you may be set something wrong somewhere along the way (or datasnapshot.val()) doesn't contain what you think it contains.
You could do this:
const keys = Object.keys(countryData); // array of the keys ["place_1", ...]
const array = Array(keys.length); // Prepares the output array of the right size
for (let i=0; i<keys.length; i++) {
const country = countryData[keys[i]]; // get the next country object
country.key = keys[i]; // add the key into the object if you need it
array[i] = country; // store the value into the array at index 'i'
}
// array now is [ {key: "place_1", description: "Sigiriya Rock Fortress"}, ...]
this.setState({countryDataArray: array});
You could try something like this. Array.prototype.push().
I have not tested below code.
componentDidMount=async() =>{
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
const datasnapshot = await firebaseHeadingref.once('value');
this.setState(prevState=>{
...prevState,
countryName,
countrydata: [...prevState.countrydata, datasnapshot.val()],
loading: false,
},()=>console.log("done!"))
}
You need to convert the response data from firebase to an array like this:
componentDidMount() {
const countryCode = this.props.match.params.countryCode;
var countryName = getName(countryCode);
var firebaseHeadingref = firebase.database().ref(countryCode);
firebaseHeadingref.once('value').then(datasnapshot => {
const countryData = datasnapshot.val();
const countryDataArray = [];
for (const key in countryData) {
countryDataArray.push({ key, ...countryData[key]});
}
this.setState({
countrydata: countryDataArray,
countryName: countryName,
loading: false
})
});
}
Use for-in to loop through the object or use Object.keys().
const data = datasnapshot.val();
const countrydata = [];
for (let key in data) {
countrydata.push(data[key])
}
// using Object.keys()
Object.keys(data).forEach((key) => countrydata.push({ [key]: data[key]}))
this.setState({
countrydata
})
const data = {
place1: { name: 'One'},
place2: { name: 'Two'},
place3: { name: 'Three'},
};
const countrydata = [];
for (let key in data) {
countrydata.push({ [key]: data[key] });
}
console.log(countrydata);

need to pass an array with an object inside it

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}`);
});
};
}

React - updating an object array in the state with setState

I'm working on a table planner app where guests can be assigned to dinner tables.
I have created an object array in the state called tabledata, which will contain objects like so:
this.state = {
tabledata: [
{
name: "Top Table",
guests: ["guest1", "guest2", "guest3"]
},
{
name: "Table One",
guests: ["guest3", "guest4", "guest5"]
}
]
}
I am then creating a drag and drop interface where guests can move between tables. I have attempted to update the state like so:
updateTableList (tablename, guest) {
const selectedTableObj = this.state.tabledata.filter((tableObj) => tableObj.name === tablename);
const otherTableObjs = this.state.tabledata.filter((tableObj) => tableObj.name !== tablename);
selectedTableObj[0].guests.push(guest);
const updatedObjectArray = [...otherTableObjs, selectedTableObj];
this.setState({
tabledata: [...otherTableObjs, ...selectedTableObj]
});
}
This works but because I am removing selectedTableObj from the state and then adding it to the end of the array I'm getting some funky results on screen. The updated table always goes to the bottom of the page (as you'd expect).
How can I update the object without changing its position within the array?
Find the index of the table you want to update using Array.findIndex(). Create a new tabledata array. Use Array.slice() to get the items before and after the updated table, and spread them into the new tabledata array. Create a new table object using object spread, add the updated guests array, and add the table object between the previous items:
Code (not tested):
updateTableList(tablename, guest) {
this.setState((prevState) => {
const tableData = prevState.tabledata;
const selectedTableIndex = tableData.findIndex((tableObj) => tableObj.name === tablename);
const updatedTable = tableData[selectedTableIndex];
return {
tabledata: [
...prevState.tabledata.slice(0, selectedTableIndex),
{
...updatedTable,
guests: [...updatedTable.guests, guest]
},
...prevState.tabledata.slice(selectedTableIndex + 1)
]
};
});
}
selectedTableObj[0].guests.push(guest) directly mutates the state which is not encouraged in React.
Try this:
this.setState((prevState) => {
const newData = [...prevState.tabledata];
// if you pass in `index` as argument instead of `tablename` then this will not be needed
const index = prevState.tabledata.findIndex(table => tableObj.name === tablename);
newData[index] = {
...newData[index],
guests: newData[index].guests.concat([guest]),
};
return { tabledata: newData };
});
You also did not remove the guest from its previous table so you need to modify for that.
You can do it with a Array.reduce
let newState = this.state
// let newState = {...this.state} // in case you want everything immutable
newState.tableData = newState.tableData.reduce((acc, table) =>
if(table.name === tableName) {
return acc.concat({...table, guests: table.guests.concat(newGuest)})
} else {
return acc.concat(table)
}
)

How can I store the attributes of objects of an array in array?

I have attributes of objects of an array that I would like to store in an array. Below is my data.
What I want to do achieve is to store displays name attribute in opt[] so it would look like this opt = ['info1', 'info2', 'info3', ... ]
getEditData (id) {
axios.get('/api/campaign/getEdit/' + id)
.then(response =>{
this.campaign = response.data.campaign;
})
.catch(e=>{
console.log(e.data);
this.error = e.data
})
}
Above snippet is the source of the campaign object
You can use this expression:
campaigns.displays.map( ({name}) => name );
const campaigns = { displays: [{ name: 'info1'}, { name: 'info2'}] };
const result = campaigns.displays.map( ({name}) => name );
console.log(result);
This will display an array containing the property names of each object in the displays array
var data = {
displays: [
{
capacity: 9000,
id: 1,
imei: 44596
}
]
};
data.displays.forEach(function(obj, idx) {
console.log(Object.keys(obj));
});
Object.keys() is what you need

Categories