0

I am trying to vue.set() an array in a "updateInformation" mutation in my vuex store.

Here is my function in my script:

 updateImagesArrayInMutation(imageFile) {
      let images = [];
      this.images.forEach(imageFile => {
        imageFile.generateBlob(
          blob => {
            let rand = (Math.random().toString(36).substring(2, 16) + Math.random().toString(36).substring(2, 16)).toUpperCase()
            let imagesRef = firestorage.ref('postimages/' + rand)
            console.log("imageRef, imageFile for eachfile", imageFile)
            if(this.images.length < 3) {
              // THIS PUSHES AN EMPTY CROPPA ("CLICK DRAGE IMAGE HERE") // max 5
              this.images.push({})
              console.log("imagesRef", imagesRef.fullPath)
            }
            this.updateImages ({ 
              images: imagesRef.fullPath
            })
          },
          'image/jpeg',
          0.8,
        )
      })
    },
    updateImages(images) {
      console.log("this is value from closure", images)
      this.updateInformation({
        images: images,
        title: this.post.title,
        description: this.post.description
      })
    },

This is the mutation in my store:

  [UPDATE_INFORMATION] (state, info) {
    console.log('[STORE MUTATIONS] - UPDATE_INFORMATION:', info)

    Vue.set(state.newPost.images, 'images', [...info.images])

    // state.newPost.images = info.images
    state.newPost.title = info.title
    state.newPost.description = info.description
    state.newPost.location = info.location
    state.newPost.city = info.city
  },

Can I do this? Thank you in advance for any suggestions.

9
  • 1
    What is the initial state of the newPost object when your store is created? Commented Jan 11, 2020 at 8:32
  • newPost: { images: '', title: '', description: '', location: '', city: '' }, Commented Jan 11, 2020 at 9:08
  • 1
    Are you trying to create an images property inside an images property? I'd guess you just want Vue.set(state.newPost, 'images', [...info.images]). Commented Jan 11, 2020 at 9:10
  • 1
    That suggests that info.images is not an array. Difficult to know what to suggest without knowing why you're trying to spread a non-array into an array. If images is just a string then why are you involving arrays at all? Commented Jan 11, 2020 at 9:20
  • 1
    @TeomanKirac see my answer below. Also, skirtle makes a good point in their answer regarding the method you use to prepare the data before committing the mutation. Commented Jan 11, 2020 at 9:58

3 Answers 3

2

Why not just do it like this:

[UPDATE_INFORMATION] (state, info, payload) {
    state.newPost = {
        ...state.newPost,
        ...info
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This will work, but the example is bad. If the state is large, then it will be completely renewed, and not partially.
1

I don't know some of the libraries you're using but I think I understand what you're trying to do. In short, you're trying to replace multiple calls to mutate the store state with a single call that passes an array of image paths.

Switch the first few lines to use Promises, like this:

const imagePromises = this.images.map(imageFile => {
  return imageFile.promisedBlob('image/jpeg', 0.8).then(blob => {

Then inside the then callback return the relevant image path rather than calling updateImages:

return imagesRef.fullPath

This will give you an array of Promises that resolve to the paths you want. You can then use Promise.all to wait for all the Promises:

Promise.all(imagePromises).then(imagePaths => {
  // imagePaths should be an array of strings
  this.updateImages(imagePaths)
})

That should get you the array of path strings that you want.

1 Comment

i see! think this is the answer, will give it a try and respond. Just really quickly however I can't get it to "return imagesRef.fullPath" for some reason.. will get back after i do more thorough attempt. . thank you.
-1

You do not need to use Vue.set(). The purpose of Vue.set() is to add new properties to an object, not to change existing properties.

In your Vuex initial state, it would make most sense to me to initialize this way:

newPost: { images: [], title: '', description: '', location: '', city: '' }

Now your images property is an array, as expected, rather than a string.

In the UPDATE_INFORMATION mutation, you can do either:

state.newPost.images = info.images

Or:

state.newPost.images = [...info.images]

If you want a shallow copy of the info.images array instead of referring to it directly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.