最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Uncaught TypeError: Cannot add property 0, object is not extensible at Array.push - Stack Overflow

programmeradmin0浏览0评论

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
Add a comment  | 

3 Answers 3

Reset to default 11

The 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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论