86

I have a function that needs to extend a javascript array, including a new attribute called selected:

export const initSelect = (data) => {

    let newData = data.concat();
    newData.map((item) => {
        item.selected = false;
    })

    return newData;
}

data is a ReactJS state value (comes from this.state.data when calling the function), but this didn't seem to be a problem as newData is a new copy of data array...

I'm getting the following error:

TypeError: Cannot add property selected, object is not extensible
Community
  • 1
  • 1
Mendes
  • 17,489
  • 35
  • 150
  • 263
  • 4
    In order to really understand this error this here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible might help. – Elmar Zander Aug 21 '20 at 09:18

4 Answers4

121

You probably need to copy the objects:

export const initSelect = (data) => {
 return data.map((item) => ({
     ...item,
     selected: false       
 }));
}
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
44

You can not extend item with selected property, and your array is just a shallow copy.

If you want to be able to extend, you will have to do a deep copy of your array. It may be enough with:

let newData = data.map((item) => 
    Object.assign({}, item, {selected:false})
)
lilezek
  • 6,976
  • 1
  • 27
  • 45
  • I see the same error with Object.assign approach. I manage to solve it using @Jonas anwer. – Rocío García Luque Sep 10 '18 at 11:01
  • Then probably you are doing something wrong @RocíoGarcíaLuque, as Jonas' solution and mine are equivalent according to my understandings of https://stackoverflow.com/a/50558264/2832398 – lilezek Dec 29 '18 at 20:16
  • 1
    You are totally right. I cannot remember the situation, but probably yes, I was doing something wrong. Your solution is perfectly valid :+1: – Rocío García Luque Dec 30 '18 at 09:55
15
data = JSON.parse(JSON.stringify(data));
Brane
  • 3,257
  • 2
  • 42
  • 53
10
const newObj = Object.assign({selected: false}, data);
Pang
  • 9,564
  • 146
  • 81
  • 122
Omar
  • 2,726
  • 2
  • 32
  • 65
  • 26
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Derek Brown Apr 30 '18 at 22:59
  • 2
    Please, keep in mind that this code afaik is not equivalent. If data already contains selected: true for example, the new object will end up with selected: true. – lilezek Jul 17 '20 at 15:05