I am getting this error when fetching data from firebase and pushing the data into an array. Here I define a temp array when I am pushing data inside firebase onValue into this temp array I am getting this error Uncaught TypeError: Cannot add property 0, object is not extensible at Array.push. Here is my code
function Room() {
const [textInput, setTextInput] = useState('');
const temp = [];
const handleTextInputChange = (event) => {
setTextInput(event.target.value);
};
const handleSubmit = () => {
console.log('here goes');
if (textInput !== '') {
const refer = ref(database, 'rooms/');
push(refer, textInput).then(() => {
setTextInput('');
toast.success('Added Successfully!');
});
}
};
useEffect(() => {
const refer = ref(database, 'rooms/');
onValue(refer, (snap) => {
snap.forEach((child) => {
console.log(child.val() + child.key);
// I am getting error in this line
temp.push({ id: child.key, firstName: child.val() });
});
});
}, []);
return (
<div>
<Grid item xs={12}>
<SubCard title="Room List">
<div style={{ height: 400, width: '100%' }}>
<DataGrid
rows={temp}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
components={{
Toolbar: CustomToolbar
}}
/>
</div>
</SubCard>
</Grid>
</div>
)
I am getting this error when fetching data from firebase and pushing the data into an array. Here I define a temp array when I am pushing data inside firebase onValue into this temp array I am getting this error Uncaught TypeError: Cannot add property 0, object is not extensible at Array.push. Here is my code
function Room() {
const [textInput, setTextInput] = useState('');
const temp = [];
const handleTextInputChange = (event) => {
setTextInput(event.target.value);
};
const handleSubmit = () => {
console.log('here goes');
if (textInput !== '') {
const refer = ref(database, 'rooms/');
push(refer, textInput).then(() => {
setTextInput('');
toast.success('Added Successfully!');
});
}
};
useEffect(() => {
const refer = ref(database, 'rooms/');
onValue(refer, (snap) => {
snap.forEach((child) => {
console.log(child.val() + child.key);
// I am getting error in this line
temp.push({ id: child.key, firstName: child.val() });
});
});
}, []);
return (
<div>
<Grid item xs={12}>
<SubCard title="Room List">
<div style={{ height: 400, width: '100%' }}>
<DataGrid
rows={temp}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
components={{
Toolbar: CustomToolbar
}}
/>
</div>
</SubCard>
</Grid>
</div>
)
Share
Improve this question
edited Oct 23, 2021 at 11:01
Ibrahim Tinku
asked Oct 23, 2021 at 10:49
Ibrahim TinkuIbrahim Tinku
1431 gold badge2 silver badges13 bronze badges
2
- I set this temp data to DataGrid – Ibrahim Tinku Commented Oct 23, 2021 at 10:58
- 1 okay, i edited my question and add that – Ibrahim Tinku Commented Oct 23, 2021 at 11:01
3 Answers
Reset to default 11The error you're getting is what you get when you try to push to a frozen array:
const temp = Object.freeze([]);
temp.push(42);
You've shown that you're passing the array to DataGrid
as rows
. Apparently, DataGrid
freezes the array, presumably because it needs to know that the contents of it don't change.
If you want to change those contents, you'll need to store temp
in state and re-render after adding to it; see ***
comments (I've also renamed temp
to dataGridRows
):
function Room() {
const [textInput, setTextInput] = useState('');
// *** Store it in state
const [dataGridRows, setDataGridRows] = useState([]);
const handleTextInputChange = (event) => {
setTextInput(event.target.value);
};
const handleSubmit = () => {
console.log('here goes');
if (textInput !== '') {
const refer = ref(database, 'rooms/');
push(refer, textInput).then(() => {
setTextInput('');
toast.success('Added Successfully!');
});
}
};
useEffect(() => {
const refer = ref(database, 'rooms/');
onValue(refer, (snap) => {
snap.forEach((child) => {
console.log(child.val() + child.key);
// *** Add to it in state; this will cause a re-render
// so DataGrid picks up the change
setDataGridRows(dataGridRows => [...dataGridRows, { id: child.key, firstName: child.val() }];
});
});
}, []);
return (
<div>
<Grid item xs={12}>
<SubCard title="Room List">
<div style={{ height: 400, width: '100%' }}>
<DataGrid
rows={dataGridRows}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
components={{
Toolbar: CustomToolbar
}}
/>
</div>
</SubCard>
</Grid>
</div>
)
}
The array is read only so what I do is just add a spread operator to it.
...
documents: [...d.distribution.documents],
...
Alternaively this worked as well
...
documents: d.distribution.documents.concat([]),
...
Thanks for the answer TJ Crowder, it helped me to understand that the real problem is not the object that you are going to pass the value, but the original object, because it is passed by reference.
So, when you have the error
object is not extensible at array
The solution is to copy the values of the original object to the target, not just assign them with the equals (=) operator.
for example
targetObject.nodes.map( (newNode: any) => {
//here I create a new object and enrich it with an array and a boolean
let newFullNode = Object.assign({}, newNode, {nodes: [] , hasChildren:true});
targetObject.nodes.push(newFullNode);
});
I update the targetObject later on, and when I was updating it, only then I was getting the error, which was misleading me.