question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

setData does not force a re-render of the component when using v-model, data(), and a computed property

See original GitHub issue

Version

1.0.0-beta.13

Reproduction link

https://github.com/s-robertson/vtu-setdata

Steps to reproduce

Create a new Vue component with the following criteria:

  1. Have data() return an object containing an empty string, e.g. msg
  2. Have a computed property that returns a boolean depending on if msg is empty or not. E.g. hasMsg
  3. Have an <input> in the component template that uses v-model, bound to msg
  4. Have an element, such as an <h1> in the component template that uses v-if, bound to hasMsg. This element must come AFTER the <input> in the template

Now write a unit test that:

  1. Mounts the component via shallow()
  2. Calls setData and sets msg to a non-empty string
  3. Checks to see if the template contains the <h1>

Finally, run the unit test.

What is expected?

Calling setData will cause the component to re-render, making hasMsg be true and the test will pass.

What is actually happening?

Calling setData does not cause the component to re-render. The unit test cannot find the <h1> element and fails:

 FAIL  tests/unit/HelloWorld.spec.js
  HelloWorld.vue
    ✕ renders props.msg when passed (36ms)

  ● HelloWorld.vue › renders props.msg when passed

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      true
    Received:
      false

       9 |     wrapper.setData({ msg });
      10 | 
    > 11 |     expect(wrapper.contains('h1')).toBe(true);
      12 |   })
      13 | });
      14 | 
      
      at Object.<anonymous> (tests/unit/HelloWorld.spec.js:11:36)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.062s
Ran all test suites.
 ERROR  jest exited with code 1.
error Command failed with exit code 1.

What’s interesting is that the order of the <input> and <h1> in the template matters. If the <h1> comes before the <input> the test will also pass.

You can also get the test to pass by forcefully updating the component via wrapper.vm.$forceUpdate(); after you’ve called setData.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

10reactions
JessicaSachscommented, Mar 12, 2020

@onomojo @rafaoliverce what do your tests look like? Are you using await wrapper.vm.$nextTick() in your tests? There was a large breaking change in v30 to remove sync mode. This requires you to await for Vue to finish the next event loop after each change that will affect the DOM.

Here are the current docs on it https://vue-test-utils.vuejs.org/guides/testing-async-components.html#updates-applied-by-vue

6reactions
An-AngryBearcommented, Sep 30, 2019

I’ve found that sometimes I have to use an async function and call await on setData and setProps

Read more comments on GitHub >

github_iconTop Results From Across the Web

Vue computed property updated, but component did not re ...
But what can explain that the computed property did update correctly, but the component did not re-render? How to fix it? Someone mentioned...
Read more >
Reactivity in Depth - Vue.js
We can debug computed properties by passing computed() a second options object with onTrack and onTrigger callbacks: onTrack will be called when a...
Read more >
Maintaining a single source of truth while handling form data ...
Set data using a activeUser watcher with deep: true — However, I decided it's probably best not to use a watcher if a...
Read more >
How to detect page is refreshed on vue? How can Vue router
Vue users should use the official @vitejs/plugin-vue-jsx plugin, ... after change vmodel data; how to reload automaticaly in vue; rerender a vue component; ......
Read more >
Using Vue.js event emitters to modify component data
​​Editor's note: This article was updated on 4 April 2022 to demonstrate modifying component data using Vue.js v.3 and Composition API.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found