benjaminadon
benjaminadon

Reputation: 153

why is this value inside array not updating inside vue.js template?

So I have a duration value inside an array that gets updated by calling a method that calculates duration every ms, using setInterval.

The problem is I'm not able to get this value to show, let alone update in the template. Here is a snippet of my vue.js code

  data() {
    return {
      job_execs: [],
      stageMatrix: [],
      liveStageDuration: {},
    }
  },
  mounted() {
    // Updates current job duration every second
    let that = this;
    setInterval(that.updateLive, 50);
  },
  methods: {
    updateLive: function() {
      // Calculate current job duration
      for (let parent = 0; parent < this.stageMatrix.length; parent++) {
        for (let item = 0; item < this.stageMatrix[parent].length; item++) {
          if (this.stageMatrix[parent][item].status.name === "IN_PROGRESS") {
            let parentId = null
            let newDuration = liveDurationMs(this.stageMatrix[parent][item].time_start)
            if (this.stageMatrix[parent][item].stage_execution_parent != null) {
              parentId = this.stageMatrix[parent][item].stage_execution_parent.name
            }
            else {
              parentId = 'none1'
            }
            this.liveStageDuration[parentId] = newDuration
            console.log(this.liveStageDuration[parentId])
          }
        }
      }
      return true
    }, 

snippet template:

<table class="hideTable">
  <tbody>
    <template v-for="row in stageMatrix">
      <tr :key="row.id">
        <template v-for="col in row">
          <template v-if="col === undefined">
            <td
              :key="col"
              class="hideCell" />
          </template>
          <template v-else>
            <td
              :key="col.id"
              :class="col.status.name"
              :title="getExecNode(col)">
              <b>
                <template v-if="col.time_end === 'N/A'">
                  {{ col.stage.name }}
                </template>
                <template v-else>
                  <a
                    :href="job_execs[0].mongo_link + col.stage.name + '.txt'">
                    {{ col.stage.name }}
                  </a>
                </template>
              </b>
              <br>
              <template v-if="col.status.name === 'IN_PROGRESS'">
                {{ liveStageDuration.none1 }}
              </template>
              <template v-else>
                {{ changeDuration(col.duration_millis) }}
              </template>
              <br>
              {{ col.status.name }}
            </td>
          </template>
        </template>
      </tr>
    </template>
  </tbody>
</table>

If I were to just set liveStageDuration: null under data and then assign the duration to this inside updateLive like this

this.liveStageDuration = newDuration

and then call liveStageDuration from the template:

{{ liveStageDuration }}

the duration will show up and update as expected. So there is something wrong with my object or array, or the template cannot see the updates made within those objects. I'm really not sure.

Upvotes: 1

Views: 190

Answers (1)

DongHak
DongHak

Reputation: 91

Again due to limitations of modern JavaScript, Vue cannot detect property addition or deletion.

For example:

   this.$set(this.someObject, 'property', value)

thus

correct code

   this.$set(this.liveStageDuration, 'parentId', newDuration)

Reference https://v2.vuejs.org/v2/guide/list.html#Caveats

Upvotes: 1

Related Questions