1

I have like this action in my app where I manupulate data inside created hook:

HTML template example:

<template>
  <div>
    <p v-for="item in items" :key="item.id">{{ item.title }}</p>
  </div>
</template>

Note: As template in my app I use vue grid layout package really

Working code:

created () {
  if(Array.isArray(this.predefinedItems)) {
    for (let index = 0; index < this.predefinedItems.length; index++) {
      this.items[index] = {...this.predefinedItems[index], ...{
        i: index, x: 1, y: 1, w: 12, h: 8, accent: 'info'
      }}
    }
    console.log(this.items)
  }
}

Not working code:

created() {
  this.emulateApiRequest()
}

methods: {
  emulateApiRequest() {
    setTimeout(() => {
      if (Array.isArray(this.predefinedItems)) {
        for (let index = 0; index < this.predefinedItems.length; index++) {
          this.items[index] = {
            ...this.predefinedItems[index],
            ...{ i: index, x: 1, y: 1, w: 12, h: 8, accent: 'info'
            }
          }
        }
        console.log(this.items)
      }
    }, 500)
  },
}

Why my template not updates when I emulate api request to set data?

2
  • Try going through the common beginner gotchas page, as well as the page on array's reactivity and array mutations. Commented Jul 13, 2021 at 4:50
  • I must use global $set method to update my array then?@NickM Commented Jul 13, 2021 at 4:59

1 Answer 1

2

The problem is you're editing items[] by index directly, which cannot be automatically detected in Vue 2. The first example only works because the created() hook occurs before the template is evaluated. The second example asynchronously updates items[], occuring after the created() hook and after the template has been evaluated.

However, Vue 2 can detect Array.prototype.push() for item insertion into an array:

for (let index = 0; index < this.predefinedItems.length; index++) {
  // this.items[index] = /*...*/
  this.items.push(/*...*/)
}

demo

Alternatively, you could set items[] to a new array instance:

const items = []
for (let index = 0; index < this.predefinedItems.length; index++) {
  items[index] = /*...*/
}
this.items = items

Or replace the for-loop with Array.prototype.map, mapping predefinedItems into a new array:

this.items = this.predefinedItems.map(item => ({
  ...item,
  i: index, x: 1, y: 1, w: 12, h: 8, accent: 'info'
}))
Sign up to request clarification or add additional context in comments.

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.