semisleep / simple-vue-validator

A simple yet flexible validator library for vue.js
MIT License
293 stars 28 forks source link

calling required on undefined value return an error #52

Open michaelAkrawi opened 6 years ago

michaelAkrawi commented 6 years ago

When trying to validate a undefined value on model throw an error. even thought docs says required() method suppose to check empty/null/undefined

null value by the way works fine

semisleep commented 6 years ago

Using undefined value is danger cuz Vue will not be able to track the change for that field. Even if the validator treats undefined as null (which is easy), the sub sequential validation will not work.

Throwing an error for undefined is deliberate here :)

lisandromc commented 5 years ago

I've run into this issue when calling this.$validate() from a validating component. In my particular case, this stems from having a select populated like this:

    <select 
        class="form-control"
        name="market_id"
        v-model="shoot.market_id"
        :class="{ 'error-field' : validation.hasError('shoot.market_id') }"
    >
        <option value="">Select a market</option>
        <option v-bind:value="market.id" v-for="market in markets" >{{market.name}}</option>
    </select>

The validator is this:

    "shoot.market_id": function(value) {
        if (value === undefined) console.log("shoot market undefined");
        return Validator.value(value).required();
    }

and the error is always:

Error: Validator.value not set
    at Rule._checkValue (rule.js?0c69:54)
    at Rule.required (rule.js?0c69:60)
    at VueComponent.shootMarket_id (step1.vue?2150:86)
    at VueComponent.eval (mixin.js?2b41:69)

The Rule class has these two methods:

    Rule.prototype._checkValue = function() {
      if (this._value === undefined) {
        throw new Error('Validator.value not set');
      }
      return this._value;
    };

    Rule.prototype.required = function (message) {
      var value = this._checkValue();
      if (utils.isEmpty(value)) {
        this._messages.push(message || this.templates.required);
      }
      return this;
    };

So my question is, why does the value come as undefined, when its default was the empty string? Conversely, if empty strings are coerced into undefined, why isn't undefined an acceptable value to run through the validation methods?

I'm new to this library and to Vue itself, so I'm most likely missing something, but I can't see why checking against an undefined/empty value should result in a code error being thrown, as opposed to a simple validation rejection.

Thanks for any help on this issue.

semisleep commented 5 years ago

Empty string will never be converted to undefined. Like I said before:

Using undefined value is danger cuz Vue will not be able to track the change for that field.

It throws error for undefined value to warn you that there might be problem in your code.

In your case, I suggest you double check if shoot.market_id field is actually initialized in the data() method, or if it's somehow removed by your code during the process.

lisandromc commented 5 years ago

Thanks for your prompt reply. It's initialized in props, not in data.

        props: {
            shoot: {
                type: Object,
            },
            step1Complete : { type : Boolean },
            step2Complete : { type : Boolean },
            step3Complete : { type : Boolean },
            step4Complete : { type : Boolean },
            step5Complete : { type : Boolean },
            step6Complete : { type : Boolean },
        },

I'll fiddle around with this to see if I can fix it that way. Thanks again.

dmoebius commented 5 years ago

I have the same problem as lisandromc and michaelAkrawi. I call $validate() on an object which has most fields undefined. Problem is that the data comes from outside and it's hard for me (though not impossible) to intercept it. I really don't want to intercept it and replace all undefined fields with null.

Except for the exception on console, everything works very well btw. The watchers created by simple-vue-validator still watch the fields, even if the initial value is undefined (or the field doesn't exist). At least that's what I observe in my setup here. So I would be glad if the check in _checkValue() would be removed. All of the default validators like required(), regex() etc. call utils.isEmpty(value) anyway, which itself handles undefined very well.