Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Cannot read property '$options' of undefined #673

Closed
feliupe opened this issue May 31, 2018 · 8 comments
Closed

TypeError: Cannot read property '$options' of undefined #673

feliupe opened this issue May 31, 2018 · 8 comments

Comments

@feliupe
Copy link

feliupe commented May 31, 2018

Version

1.0.0-beta.15

Reproduction link

https://github.com/feliupe/vuerror

Steps to reproduce

yarn && yarn test

What is expected?

The test to run with no error.

What is actually happening?

There two errors:

  • TypeError: Cannot read property '$options' of undefined
  • and TypeError: Cannot set property '_error' of undefined, that I think is related to the errorHandler and my not be related to the test failing.
    TypeError: Cannot read property '$options' of undefined

       6 |     it('Mock', () => {
       7 |         const wrapper = mount(Page)
    >  8 |         wrapper.vm.treeData = {}
       9 |         // wrapper.vm.$forceUpdate()
      10 |     })
      11 | })
      
      at updateChildComponent (node_modules/vue/dist/vue.js:2573:8)
      at prepatch (node_modules/vue/dist/vue.js:3510:5)
      at patchVnode (node_modules/vue/dist/vue.js:5425:7)
      at updateChildren (node_modules/vue/dist/vue.js:5340:9)
      at patchVnode (node_modules/vue/dist/vue.js:5436:29)
      at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.js:5566:9)
      at VueComponent.Vue._update (node_modules/vue/dist/vue.js:2428:19)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.js:2542:10)
      at Watcher.get (node_modules/vue/dist/vue.js:2883:25)
      at Watcher.run (node_modules/vue/dist/vue.js:2960:22)
      at Watcher.update (node_modules/vue/dist/vue.js:2948:10)
      at Dep.notify (node_modules/vue/dist/vue.js:784:13)
      at Object.reactiveSetter [as treeData] (node_modules/vue/dist/vue.js:1006:11)
      at updateChildComponent (node_modules/vue/dist/vue.js:2599:18)
      at prepatch (node_modules/vue/dist/vue.js:3510:5)
      at patchVnode (node_modules/vue/dist/vue.js:5425:7)
      at updateChildren (node_modules/vue/dist/vue.js:5340:9)
      at patchVnode (node_modules/vue/dist/vue.js:5436:29)
      at updateChildren (node_modules/vue/dist/vue.js:5340:9)
      at patchVnode (node_modules/vue/dist/vue.js:5436:29)
      at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.js:5566:9)
      at VueComponent.Vue._update (node_modules/vue/dist/vue.js:2428:19)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.js:2542:10)
      at Watcher.get (node_modules/vue/dist/vue.js:2883:25)
      at Watcher.run (node_modules/vue/dist/vue.js:2960:22)
      at Watcher.update (node_modules/vue/dist/vue.js:2948:10)
      at VueComponent.Vue.$forceUpdate (node_modules/vue/dist/vue.js:2449:19)
      at updateChildComponent (node_modules/vue/dist/vue.js:2615:8)
      at prepatch (node_modules/vue/dist/vue.js:3510:5)
      at patchVnode (node_modules/vue/dist/vue.js:5425:7)
      at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.js:5566:9)
      at VueComponent.Vue._update (node_modules/vue/dist/vue.js:2428:19)
      at VueComponent.updateComponent (node_modules/vue/dist/vue.js:2542:10)
      at Watcher.get (node_modules/vue/dist/vue.js:2883:25)
      at Watcher.run (node_modules/vue/dist/vue.js:2960:22)
      at Watcher.update (node_modules/vue/dist/vue.js:2948:10)
      at Dep.notify (node_modules/vue/dist/vue.js:784:13)
      at Object.reactiveSetter [as treeData] (node_modules/vue/dist/vue.js:1006:11)
      at VueComponent.proxySetter [as treeData] (node_modules/vue/dist/vue.js:3075:26)
      at Object.it (test/Test.spec.js:8:9)

  console.error node_modules/vue/dist/vue.js:667
    TypeError: Cannot set property '_error' of undefined
        at errorHandler (/home/feliupe/archii/vuerror/node_modules/@vue/test-utils/dist/vue-test-utils.js:5126:13)
        at handleError (/home/feliupe/archii/vuerror/node_modules/vue/dist/vue.js:565:25)
        at Array.<anonymous> (/home/feliupe/archii/vuerror/node_modules/vue/dist/vue.js:709:11)
        at nextTickHandler (/home/feliupe/archii/vuerror/node_modules/vue/dist/vue.js:654:16)
        at <anonymous>

I tried to create the minimum setup to reproduce the problem. Almost any statement you remove from this code will make the test pass. Like removing <message/> for example.

You may ask, why this setup of components, with a Tree and Message wrapped in a Layout: it's a representation of what I have in my project.

May also help to know that the error disappears if you remove wrapper.vm.treeData = {} and also happens if you uncomment wrapper.vm.$forceUpdate().

@eddyerburgh
Copy link
Member

Thanks for the bug report.

This is the same issue filed here—#653.

This is a problem with how we have implemented synchronous updating. There's a PR open to fix this by adding an async option to Vue—vuejs/vue#8240.

For the moment, the workaround is to set the sync mounting option to false and use Vue.nextTick to await DOM updates:

test('use Vue.nextTick', (done) => {
  const wrapper = mount(TestComponent, { sync: false })
  wrapper.trigger('click')
  Vue.nextTick(() => {
    expect(wrapper.text()).toBe('updated')
    done()
  })
})

@nathan-isaac
Copy link

nathan-isaac commented Jul 4, 2018

I ran into this issue myself. However, I couldn't get Edd Yerburgh solution to work for me. I was working with a form submit trigger event.

I ended up using the flushPromises method from https://www.npmjs.com/package/flush-promises.

test('use Vue.nextTick', async () => {
  const wrapper = mount(TestComponent, { sync: false })
  wrapper.trigger('submit')
  await flushPromises()
  expect(wrapper.text()).toBe('updated')
})

Update

My above example actually didn't work as expected. Here is what I changed.

test('use Vue.nextTick', async () => {
  const wrapper = mount(TestComponent, { sync: false })
  wrapper.trigger('submit')
  await wrapper.vm.$nextTick()
  expect(wrapper.text()).toBe('updated')
})

@mwangaben
Copy link

@nathanjisaac thanks men this is huge serve !

@rndmerle
Copy link

rndmerle commented Feb 8, 2019

I've updated to @vue/test-utils 1.0.0-beta.29 and vue 2.5.22 and I've the same issue.

I pulled out a minimal reproduction on https://github.com/rndmerle/repro-vue-test-utils-sync.git
Just yarn && yarn test

The test would pass if you change either one of those:

  • comment out one of the two it()
  • comment out the content of the forEach (in setup method)
  • switch the watcher to immediate:false and uncomment the created() content

I can't find anything further down, my brain is boiling.

@eddyerburgh
Copy link
Member

Thanks for the reproduction @rndmerle, this is caused by sync mode, which is being deprecated. See this issue for more details—#1137

@rndmerle
Copy link

rndmerle commented Feb 8, 2019

Yea but I thought #1062 would solve that somehow. I misunderstood something I guess.
Thanks for the details.

@eddyerburgh
Copy link
Member

We were hoping #1062 would be a medium-term solution, but there are lots of edge cases we didn't anticipate.

@rndmerle
Copy link

rndmerle commented Feb 8, 2019

It's clearer now thanks ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants