Vue-form-generator: Property or method "debouncedValidate" is not defined on the instance but referenced during render

Created on 14 Nov 2017  路  14Comments  路  Source: vue-generators/vue-form-generator

I've created a custom field for postcode. but I got error in console."Property or method "debouncedValidate" is not defined on the instance but referenced during render "

<template>
  <input
      class="form-control"
      type="tel"
      v-model="value"
      :disabled="disabled"
      :maxlength="schema.maxlength"
      :placeholder="schema.placeholder"
      :readonly="schema.readonly"
      :formmethod="schema.formmethod"
      :debouncedValidate="schema.validator"
      @input="onEnter($event)"
      >
</template>

<script>
  import { abstractField } from "vue-form-generator";
  import { getConfig } from '../utils/api'
  export default {
    mixins: [ abstractField ],
    methods: {
      onEnter(event){
        this.value = this.value.replace(/[^0-9-]+/,'')
      }
    }
  };
</script>

something i missed?

bug easy

Most helpful comment

Ok, I think I've tracked the issue down ... it looks like the older version of Vue that VFG was originally written against supported adding methods to the Vue components dynamically. However, the newer version of Vue is throwing errors because "debouncedValidate" is not defined in the component, as it was being attached only in certain situations. This seems to only occur if you're using a newer version of Vue than VFG was intended for.

Working on a fix now.

All 14 comments

You didn't define it. It's not a property defined in abstractField, it's part of the computed value.

When adding your custom field to the form, just provide a validateDebounceTime value in the field schema and it will create a debounce() function and call it for you.

Take a look at src/fields/core/fieldInput.vue for an example of a basic input[type=text] field.

Looks like you're trying to mask the input entered, which can be done using the formatValueToField and formatValueToModel methods, in a similar fashion to how src/fields/core/fieldInput.vue handles dates. You should remove the @input, and include the custom logic in the formatValueTo* methods.

I'll take a look on it. thank you!

I rewrite my custom filed in the following way with some console.log() to test.
but I still caught the same error.I did something wrong?

<template>
  <input
      class="form-control"
      :id="getFieldID(schema)"
        :type="schema.inputType"
        :value="value"
        @input="value = $event.target.value"
        :class="schema.fieldClasses"
        @change="schema.onChange || null"
        :disabled="disabled"
        :accept="schema.accept"
        :alt="schema.alt"
        :autocomplete="schema.autocomplete"
        :checked="schema.checked"
        :dirname="schema.dirname"
        :formaction="schema.formaction"
        :formenctype="schema.formenctype"
        :formmethod="schema.formmethod"
        :formnovalidate="schema.formnovalidate"
        :formtarget="schema.formtarget"
        :height="schema.height"
        :list="schema.list"
        :max="schema.max"
        :maxlength="schema.maxlength"
        :min="schema.min"
        :minlength="schema.minlength"
        :multiple="schema.multiple"
        :name="schema.inputName"
        :pattern="schema.pattern"
        :placeholder="schema.placeholder"
        :readonly="schema.readonly"
        :required="schema.required"
        :size="schema.size"
        :src="schema.src"
        :step="schema.step"
        :width="schema.width"
        :files="schema.files"
      >
</template>

<script>
  import { abstractField } from "vue-form-generator";
  import { getConfig } from '../utils/api'
  export default {
    mixins: [ abstractField ],
    methods: {
      formatValueToField(value) {
            if (value != null) {
          console.log(77777)
            }

            return value;
        },

        formatValueToModel(value) {
            if (value != null) {
          console.log(99999)
            }

            return value;
        }
    }
  };
</script>

Can you provide a JSFiddle of this? I copied your custom field to my project and used it, ... I got an error about the "getConfig" as ../utils/api is the wrong path for a custom field (assuming you put the field in your project, and not in the node_modules/vue-form-generator/src/fields folder. getConfig isn't being used, so I just removed it ... after that, your custom field showed up in my form and output "99999" to my console with no warnings/errors.

here is the jsfiddle:https://jsfiddle.net/egfkqt7a/
I found that if I put the custom field in the following way within the file I wrote my VFG,there is no error:

//custom field postcode
Vue.component("field-postcode", {
    template: '<input class="form-control" :id="getFieldID(schema)" :type="schema.inputType" :value="value" @input="value = $event.target.value" :class="schema.fieldClasses" @change="schema.onChange || null" :disabled="disabled" :accept="schema.accept" :alt="schema.alt" :autocomplete="schema.autocomplete" :checked="schema.checked" :dirname="schema.dirname" :formaction="schema.formaction" :formenctype="schema.formenctype" :formmethod="schema.formmethod" :formnovalidate="schema.formnovalidate" :formtarget="schema.formtarget" :height="schema.height" :list="schema.list" :max="schema.max" :maxlength="schema.maxlength" :min="schema.min" :minlength="schema.minlength" :multiple="schema.multiple" :name="schema.inputName" :pattern="schema.pattern" :placeholder="schema.placeholder" :readonly="schema.readonly" :required="schema.required" :size="schema.size" :src="schema.src" :step="schema.step" :width="schema.width" :files="schema.files" />',
 mixins: [ VueFormGenerator.abstractField ],
 methods: {
 formatValueToField(value) {
  if (value != null) {
   console.log(77777)
  }
  return value;
 },

 formatValueToModel(value) {
  if (value != null) {
   console.log(99999)
  }

  return value;
 }
}

//add the postcode in the VFG schema
export default {
    data() {
      return {
        model: {
          postalCode: '',
        },
        schema: {
          fields: [{
              type: "postcode",
              label: "C贸digo postal de la empresa",
              model: "postalCode",
              maxlength: 5,
              required: true,
            }]
         }
      }
...

However, when I import the customField component from another file like the
document said, the error " ...'debouncedValidate' is not defined..." shows.

...
import fieldPostcode from "./fieldPostcode.vue";
Vue.component("fieldPostcode", fieldPostcode);

//add the postcode in the VFG schema
export default {
    data() {
      return {
        model: {
          postalCode: '',
        },
        schema: {
          fields: [{
              type: "postcode",
              label: "C贸digo postal de la empresa",
              model: "postalCode",
              maxlength: 5,
              required: true,
            }]
         }
      }
...

@gezichenshan how do I reproduce the error using your Fiddle? When I enter values into your Postcode field all I get is 99999 and 77777 output to the console depending on the input. No errors about debounceValidate.

@zoul0813 Yes , in Fiddle there is no errors. I've explained in my last comment that if I use the Postcode field by importing it from another file, the errors show.

@gezichenshan I copied everything over to a local project, and imported the "fieldPostcode.vue" file and am still unable to reproduce the issue you're reporting. Without a JSFiddle/Plunker showing the error or a git repo that can be cloned and tested ... I can't help you.

Are you using the latest version of VFG (2.1.1) ?

Yes I'm using the latest version 2.1.1.
Here is my project structure:

-components
  ...
  -Reg1.vue
  ...
  -fieldPostcode.vue
  ...

fieldPostcode.vue:

<template>
  <input
      class="form-control"
      :id="getFieldID(schema)"
        :type="schema.inputType"
        :value="value"
        @input="value = $event.target.value"
        :class="schema.fieldClasses"
        @change="schema.onChange || null"
        :disabled="disabled"
        :accept="schema.accept"
        :alt="schema.alt"
        :autocomplete="schema.autocomplete"
        :checked="schema.checked"
        :dirname="schema.dirname"
        :formaction="schema.formaction"
        :formenctype="schema.formenctype"
        :formmethod="schema.formmethod"
        :formnovalidate="schema.formnovalidate"
        :formtarget="schema.formtarget"
        :height="schema.height"
        :list="schema.list"
        :max="schema.max"
        :maxlength="schema.maxlength"
        :min="schema.min"
        :minlength="schema.minlength"
        :multiple="schema.multiple"
        :name="schema.inputName"
        :pattern="schema.pattern"
        :placeholder="schema.placeholder"
        :readonly="schema.readonly"
        :required="schema.required"
        :size="schema.size"
        :src="schema.src"
        :step="schema.step"
        :width="schema.width"
        :files="schema.files"
      >
</template>

<script>
  import { abstractField } from "vue-form-generator";
  import { getConfig } from '../utils/api'
  export default {
    mixins: [ abstractField ],
    methods: {
      formatValueToField(value) {
            if (value != null) {
          console.log(77777)
            }

            return value;
        },

        formatValueToModel(value) {
            if (value != null) {
          console.log(99999)
            }

            return value;
        }
    }
  };
</script>

Reg1.vue:

<template>
....
</template>
<script>
...
import fieldPostcode from "./fieldPostcode.vue";
Vue.component("fieldPostcode", fieldPostcode);
...
schema: {
          fields: [
            {
              type: "postcode",
              label: "C贸digo postal de la empresa",
              model: "postalCode",
              maxlength: 5,
              required: true,
              validator: function (value, field, model) {
                let postcode = value
                return checkpostcode(postcode).then((result) => {
                  console.log(result)
                }).catch((error) => {
                  let data = error.response.data
                  let msg = data.msg
                  return [msg]
                })
              },
              styleClasses: 'col-12 col-sm-6 col-md-4',
            },
           ]
}
...
</script>
<style>
...
</style>

If I use the fieldPostcode by importing it from another file fieldPostcode.vue, the error shows. By If I did it in the following way within a single file锛宼here is no errors. I don't know the differences.
Reg1.vue

<template>
....
</template>
<script>
...
//import fieldPostcode from "./fieldPostcode.vue"; **delete this two line**
//Vue.component("fieldPostcode", fieldPostcode); **delete this two line**

//custom field postcode
Vue.component("field-postcode", {
    template: '<input class="form-control" :id="getFieldID(schema)" :type="schema.inputType" :value="value" @input="value = $event.target.value" :class="schema.fieldClasses" @change="schema.onChange || null" :disabled="disabled" :accept="schema.accept" :alt="schema.alt" :autocomplete="schema.autocomplete" :checked="schema.checked" :dirname="schema.dirname" :formaction="schema.formaction" :formenctype="schema.formenctype" :formmethod="schema.formmethod" :formnovalidate="schema.formnovalidate" :formtarget="schema.formtarget" :height="schema.height" :list="schema.list" :max="schema.max" :maxlength="schema.maxlength" :min="schema.min" :minlength="schema.minlength" :multiple="schema.multiple" :name="schema.inputName" :pattern="schema.pattern" :placeholder="schema.placeholder" :readonly="schema.readonly" :required="schema.required" :size="schema.size" :src="schema.src" :step="schema.step" :width="schema.width" :files="schema.files" />',
 mixins: [ VueFormGenerator.abstractField ],
 methods: {
 formatValueToField(value) {
  if (value != null) {
   console.log(77777)
  }
  return value;
 },

 formatValueToModel(value) {
  if (value != null) {
   console.log(99999)
  }

  return value;
 }
}
...
schema: {
          fields: [
            {
              type: "postcode",
              label: "C贸digo postal de la empresa",
              model: "postalCode",
              maxlength: 5,
              required: true,
              validator: function (value, field, model) {
                let postcode = value
                return checkpostcode(postcode).then((result) => {
                  console.log(result)
                }).catch((error) => {
                  let data = error.response.data
                  let msg = data.msg
                  return [msg]
                })
              },
              styleClasses: 'col-12 col-sm-6 col-md-4',
            },
           ]
}
...
</script>
<style>
...
</style>

Thank you for your help. If you cannot reproduce my error, that's ok, let's make it done! I appreciate your kindness .

I'm still not able to reproduce the error. However, you're Reg1.vue file is incomplete and I had to make some assumptions about how you declared the ...

I went with ...

<vue-form-generator :schema="schema" :model="model"></vue-form-generator>

You shouldn't be getting errors about debouncedValidate unless you're trying to use the debounce validation ... the code that calls 'debouncedValidate' is located in abstractField's computed setter for 'value'.

/// VFG debouncedValidate logic
if (this.$parent.formOptions && this.$parent.formOptions.validateAfterChanged === true) {
    if (this.$parent.formOptions.validateDebounceTime > 0) {
        if (!this.debouncedValidate)
            this.debouncedValidate = debounce(this.validate.bind(this), this.$parent.formOptions.validateDebounceTime);

        this.debouncedValidate();
    } else {
        this.validate();
    }
}

Even when I pass a formOptions object as { validateAfterChanged: true, validateDebounceTime: 5000 } I still don't get an error ... unfortunately, without having an actual project that reproduces the error I can't help. I'm going to close this issue for now, feel free to re-open it later if you can provide a complete project (something I can clone from github, or a JSFiddle/Plunker) that reproduces the reported error.

@zoul0813 Hi, I created a project on github to reproduce the error. You may check it out if it is convenient for you.
Here it is: https://github.com/gezichenshan/vfg-custom-postalcode-field-demo :)
You may see the error in console.

I can reproduce the error in your project, ... taking a look at it now.

Ok, I think I've tracked the issue down ... it looks like the older version of Vue that VFG was originally written against supported adding methods to the Vue components dynamically. However, the newer version of Vue is throwing errors because "debouncedValidate" is not defined in the component, as it was being attached only in certain situations. This seems to only occur if you're using a newer version of Vue than VFG was intended for.

Working on a fix now.

@zoul0813 Thank you very much!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Atiladanvi picture Atiladanvi  路  4Comments

dflock picture dflock  路  5Comments

sjordan1975 picture sjordan1975  路  5Comments

icetee picture icetee  路  4Comments

miseeger picture miseeger  路  4Comments