Skip to content
This repository has been archived by the owner on Dec 25, 2017. It is now read-only.

TypeError: Cannot read property 'minlength' of undefined #130

Closed
marcotaubmann opened this issue Jan 12, 2016 · 17 comments
Closed

TypeError: Cannot read property 'minlength' of undefined #130

marcotaubmann opened this issue Jan 12, 2016 · 17 comments
Labels

Comments

@marcotaubmann
Copy link

With vue 1.0.14 and vue-validator 2.0.0-alpha.9 I get this TypeError when my component that contains a validator with <input type="text" v-validate:comment="{ minlength: 16, maxlength: 128 }"> is loading. Thus the component won't show up.

My components data attribute is like:

data: function () {
  return {
    comment:"",
    ...
  }
}

When I change something e.g. the minlength to 5, the component is reloaded by webpack hot module reload and then the component and the validator works.

Is this a vue-validator bug or is something wrong with my setup?

Here is the Error Stack

Uncaught (in promise) TypeError: Cannot read property 'minlength' of undefined
resolveAsset    @   vue.js:1893
_resolveValidator   @   vue-validator.common.js:586
(anonymous function)    @   vue-validator.common.js:528
each    @   vue-validator.common.js:133
validate    @   vue-validator.common.js:527
(anonymous function)    @   vue-validator.common.js:976
each    @   vue-validator.common.js:133
validate    @   vue-validator.common.js:975
update  @   vue-validator.common.js:415
Directive._bind @   vue.js:7786
linkAndCapture  @   vue.js:6435
compositeLinkFn @   vue.js:6413
Fragment    @   vue.js:4418
FragmentFactory.create  @   vue.js:4634
insert  @   vue.js:4676
insert  @   vue-validator.common.js:1207
render  @   vue-validator.common.js:1202
(anonymous function)    @   vue-validator.common.js:1191
(anonymous function)    @   vue.js:216
_dir.vm.(anonymous function)    @   vue-validator.common.js:1023
bind    @   vue-validator.common.js:1196
Directive._bind @   vue.js:7751
linkAndCapture  @   vue.js:6435
compositeLinkFn @   vue.js:6413
Vue._compile    @   vue.js:8035
Vue.$mount  @   vue.js:9027
Vue._init   @   vue.js:2410
Vue._init   @   vue-router.js:1704
Override.Vue._init  @   vue-validator.common.js:361
VueComponent    @   VM7721:2
...
@kazupon
Copy link
Owner

kazupon commented Jan 13, 2016

Related #35 #103 #111

@marcotaubmann
Copy link
Author

Thank you for the hint.

The related issues say that the code

Vue.config.warnExpressionErrors = false
Vue.config.debug = false

should avoid this problem at least for development and that it will be fixed in the future.

But if I apply that two settings I still get the error. In my console I don't get the [Vue warn]: Error when evaluating expression like in the related issues.

@marcotaubmann
Copy link
Author

Found the problem. I'm sure it's related to my project setup and not a vue-validator bug. Sorry for the false alarm.

If you are interested here are my related files boiled down.

index.js

import Vue from 'vue'
import router from './router'
import VueValidator from 'vue-validator'
import App from './App.vue'

Vue.use(VueValidator)

router.start(App, '#app')

router.js

import Vue from 'vue'
import VueRouter from 'vue-router'

import Home from './Home.vue'
import SomeComponentThatUsesValidator from './SomeComponent.vue'

Vue.use(VueRouter)

var router = new VueRouter()

router.map({
    '/home': {component: Home, name: 'home'},
    '/validatestuff': {component: SomeComponentThatUsesValidator}
})

export default router

I think the Problem is that the Vue.use(VueValidator) from index.js is executed after the router.js and after the components using the validator are loaded. This would also explain why there were no problems after updating the component with hot module reload, because then the Vue.use(VueValidator) would have already been applied.

When I import and use the vue-validator in the beginning of router.js it works. It maybe would be an even better application setup to let router.js export a router factory function which accepts the Vue or so. Or simply integrate the setup from router.js into index.js. But that is really not related to this issue anymore. :)

@kazupon
Copy link
Owner

kazupon commented Jan 13, 2016

No problem 😺
Enjoy vue.js. 😸

@tylersnyder
Copy link

@kazupon I'm having this issue as well, using v2.0.0-alpha.18 with vue@1.0.16. This error is thrown and prevents my app from rendering, even if I set Vue.config.debug and Vue.config.warnExpressionErrors to false.

Uncaught TypeError: Cannot read property 'minlength' of undefined

resolveAsset @ vue.common.js?e881:1914
_resolveValidator @ vue-validator.common.js?d93a:777
(anonymous function) @ vue-validator.common.js?d93a:690
each @ vue-validator.common.js?d93a:135
validate @ vue-validator.common.js?d93a:689
(anonymous function) @ vue-validator.common.js?d93a:1450
each @ vue-validator.common.js?d93a:135
validate @ vue-validator.common.js?d93a:1449
update @ vue-validator.common.js?d93a:443
Directive._bind @ vue.common.js?e881:7858
linkAndCapture @ vue.common.js?e881:6508
compositeLinkFn @ vue.common.js?e881:6477
Fragment @ vue.common.js?e881:4462
FragmentFactory.create @ vue.common.js?e881:4679
insert @ vue.common.js?e881:4721
(anonymous function) @ vue-validator.common.js?d93a:1722
_dir.vm.(anonymous function) @ vue-validator.common.js?d93a:1511
setupFragment @ vue-validator.common.js?d93a:1728
bind @ vue-validator.common.js?d93a:1680
Directive._bind @ vue.common.js?e881:7823
linkAndCapture @ vue.common.js?e881:6508
compositeLinkFn @ vue.common.js?e881:6477
Fragment @ vue.common.js?e881:4462
FragmentFactory.create @ vue.common.js?e881:4679
insert @ vue.common.js?e881:4721
update @ vue.common.js?e881:4709
Directive._bind @ vue.common.js?e881:7858
linkAndCapture @ vue.common.js?e881:6508
compositeLinkFn @ vue.common.js?e881:6477
Vue._compile @ vue.common.js?e881:8107
Vue.$mount @ vue.common.js?e881:9098
Vue._init @ vue.common.js?e881:2439
Override.Vue._init @ vue-validator.common.js?d93a:386
Vue._init @ vue-router.js?e71f:1724
EditVehicleComponent @ VM26619:2
build @ vue.common.js?e881:6047
activate @ vue-router.js?e71f:1162
bind @ vue-router.js?e71f:1822
Directive._bind @ vue.common.js?e881:7823
linkAndCapture @ vue.common.js?e881:6508
compositeLinkFn @ vue.common.js?e881:6477
Fragment @ vue.common.js?e881:4462
FragmentFactory.create @ vue.common.js?e881:4679
remove @ vue.common.js?e881:4731
update @ vue.common.js?e881:4712
_update @ vue.common.js?e881:7835
Watcher.run @ vue.common.js?e881:3286
runBatcherQueue @ vue.common.js?e881:3019
flushBatcherQueue @ vue.common.js?e881:2995
nextTickHandler @ vue.common.js?e881:432

@kazupon
Copy link
Owner

kazupon commented Feb 6, 2016

@tylersnyder
Thank you for your reporting!!

Can you provide the reproduction codes with jsfiddle or etc please ?

@tylersnyder
Copy link

@kazupon

I was unable to reproduce the issue using jsfiddle. http://jsfiddle.net/9x3mxvj0/13/

This helped me realize I was probably misunderstanding something. My project is using webpack and I have many components broken up into separate files. It didn't occur to me that each component may need to import or require VueValidator.

I had only added the dependency to my main entry file, similar to how VueRouter is used. After adding the following to each component file, my project seems to be working as expected.

import Vue from 'vue'
import Validator from 'vue-validator'
Vue.use(Validator)

I believe others who are attempting to use your project are running into similar issues - caused by confusion, rather than bugs. Improving documentation may help with this.

Thank you for your reply, and your work on this project.

@kazupon
Copy link
Owner

kazupon commented Feb 8, 2016

@tylersnyder

Thank you for your jsfiddle code.
I hope that your project goes well. 😺

@devinchen
Copy link

@tylersnyder
Thank you, that snippet really save my life !

@kazupon
BTW, is there any way to register vue-validator plugin only once?

@kazupon
Copy link
Owner

kazupon commented Mar 22, 2016

You can use 'Vue.use' at the entry point.

@murbanowicz
Copy link

I have it like that in my entry point:

// vue-validator
var VueValidator = require('vue-validator');
Vue.use(VueValidator);

before vue-router etc.
and I am getting Cannot get minLength/required/maxLength' of underfined

Any help?

@wklc2014
Copy link

wklc2014 commented Jul 4, 2016

@mariaczi hello, do you solve this problem for install vue-validator before route.map method?
I has write as that, but I still report which mistakes

@wklc2014
Copy link

wklc2014 commented Jul 7, 2016

@tylersnyder hello, the problem that the plugin users have to install vue-validator plugin for each form component is resolve?
in my project, At first, I install the plugin at my entry point that route.js or main.js for example (route.js is my project for define app route and main.js is webpack entry file), But there was problem like

Uncaught TypeError: Cannot read property 'required' of undefined

And then, I import and install it in my form component, it work.
So probably solve the problem of the use of this plugin, But I think it so trouble, is there any thing for it?
thank you

@tylersnyder
Copy link

tylersnyder commented Jul 7, 2016

@wklc2014, I was able to load VueValidator in only one spot by putting it in my top level component, App.vue, which is then passed into the router. It looks something like this:

App.vue:

import Vue from 'vue' 
import VueValidator from 'vue-validator'

Vue.use(VueValidator)

...define and export App component

router:
router.start(App, 'app')

VueValidator is then passed into all of my child components which are loaded inside of App. I hope this helps!

@wklc2014
Copy link

wklc2014 commented Jul 8, 2016

@tylersnyder Thank you very much for your help, it work.
before this, somebody tell me that I should install vue-validator plugin before route.map as some reason if I use vue-router, so I do that in route.js file.
As you said, install this plugin in app.js is good idea.
Thank you again for your help

@nandin-borjigin
Copy link

Working solution:

I was able to load VueValidator in only one spot by putting it in my top level component, App.vue, which is then passed into the router. It looks something like this:
App.vue:

import Vue from 'vue' 
import VueValidator from 'vue-validator'
Vue.use(VueValidator)

...define and export App component
router:

router.start(App, 'app')

VueValidator is then passed into all of my child components which are loaded inside of App. I hope this helps!

Before this, I've tried the trick in #188 ,which is now added in documentation

if you are using vue-router, you must install with Vue.use() in advance of instance methods (router#map, router#start, ...etc).

THIS DOESN'T WORK, AT LEAST IN MY SITUATION.
There is my setup file ( webpack entry file ) looked like:

import Vue from 'vue'
import Validator from 'vue-validator'
Vue.use(Validator)
import Router from 'vue-router'

import App from './components/App.vue'
//import other components

Vue.use(Router)
Vue.use(Resource)

the vue-validator was installed before the vue-router, but the exception was still there

@kazupon So, I think this "bug" may not only related to the installation sequence, and the documentation probably write this solution down.

@kenberkeley
Copy link

kenberkeley commented Aug 6, 2016

@tylersnyder I love you man, you saved my life...
BTW, I do try putting Vue.use(VueValidator) in App.vue or main.js
But still not working for Webpack Code-Splitting SPA.
So I have a single initialization file named initValidator.js:

import Vue from 'vue'
import VueValidator from 'vue-validator'
Vue.use(VueValidator)

If I need form validation in a component, just do it:

import 'path/to/initValidator'
export default { ......Component...... }

P.S: No need to do this in entry file before use vue-router.

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

No branches or pull requests

8 participants