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

Property or method "debouncedValidate" is not defined on the instance but referenced during render #345

Closed
gezichenshan opened this issue Nov 14, 2017 · 14 comments

Comments

@gezichenshan
Copy link
Contributor

gezichenshan commented Nov 14, 2017

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?

@zoul0813
Copy link
Member

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.

@gezichenshan
Copy link
Contributor Author

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

@gezichenshan
Copy link
Contributor Author

gezichenshan commented Nov 15, 2017

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>

@zoul0813
Copy link
Member

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.

@gezichenshan
Copy link
Contributor Author

gezichenshan commented Nov 23, 2017

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,
            }]
         }
      }
...

@zoul0813
Copy link
Member

@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.

@gezichenshan
Copy link
Contributor Author

gezichenshan commented Nov 28, 2017

@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.

@zoul0813
Copy link
Member

@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) ?

@gezichenshan
Copy link
Contributor Author

gezichenshan commented Nov 30, 2017

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,there 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 .

@zoul0813
Copy link
Member

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.

@gezichenshan
Copy link
Contributor Author

gezichenshan commented Dec 5, 2017

@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.

@zoul0813
Copy link
Member

zoul0813 commented Dec 5, 2017

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

@zoul0813 zoul0813 reopened this Dec 5, 2017
@zoul0813
Copy link
Member

zoul0813 commented Dec 5, 2017

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 added a commit to zoul0813/vue-form-generator that referenced this issue Dec 5, 2017
* feature/345-debounced-validate-fix:
  remove uniqueId import
  fixes vue-generators#345 - declare debouncedValidateFunc and set it when debouncedValidate() is called... vue 2.2.0 prevents you from attaching methods/properties to components that have not been declared
zoul0813 added a commit to zoul0813/vue-form-generator that referenced this issue Dec 5, 2017
* feature/345-debounced-validate-fix:
  remove uniqueId import
  fixes vue-generators#345 - declare debouncedValidateFunc and set it when debouncedValidate() is called... vue 2.2.0 prevents you from attaching methods/properties to components that have not been declared
@icebob icebob closed this as completed in ee684f0 Dec 5, 2017
icebob added a commit that referenced this issue Dec 5, 2017
@gezichenshan
Copy link
Contributor Author

@zoul0813 Thank you very much!

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

No branches or pull requests

2 participants