Home > Software design >  Why is Array.push() throwing an error but Array.concat() does not?
Why is Array.push() throwing an error but Array.concat() does not?

Time:06-14

I am trying to add an array to an existing array. The initial data is like this:

Form = reactive({ 
          Title: null,
          Files: [ 
                   {name: "photo", extension: ".webp" size: '1024'}, 
                   {name: "doc", extension: ".pdf" size: '2048'}
                 ]
       )}

Form.Files may also be an empty array [ ] if there are no existing files when the form is loaded.

When the user adds new files, the data for the new files is like this:

NewFiles = [
              [
               File, 
               {name: "newphoto", extension: ".jpg", size: "1024" }
              ],
              [
               File, 
               {name: "newdoc", extension: ".docx", size: "2048" }
              ]
           ]

File is the file object itself as selected via an input field e.g. <input multiple type="file" />

So how do we add NewFiles to Form.Files? I tried the following:

Form.Files.push(...NewFiles);

That somewhat works in that the Vue debugger shows the NewFiles array added to Form.Files, but it thrown an error of [vuex] do not mutate vuex store state outside mutation handlers. and the rest of the code fails.

So I tried concat() which works:

const AllFiles = Form.Files.concat(NewFiles);
Form.BroadcastFiles = AllFiles;

There's no errors but I don't understand why push() would cause a Vuex error when I'm not touching any Vuex state, and even if I was, why doesn't the contact() cause the same error?

CodePudding user response:

I suggest you check this article about the use of spread operator in Javascript, and array reference How to Use the Spread Operator (…) in JavaScript especially the "A note about copying by reference" section. So basically you are mutating the state of Form.Files while using concat and you are losing the reference using the spread operator. One solution can be:

let AllFiles = [...Form.Files];
AllFiles.concat(NewFiles);
Form.BroadcastFiles = AllFiles;

CodePudding user response:

.concat returns a new array with both the current items and the new ones where .push modifies the current array instead of returning a new one.

If that array was initially loaded from vuex it results in an unwanted mutation of the store.

  • Related