Infinite loop when using :value and @input #190
Replies: 14 comments
-
You need to learn vue.js concepts first. Please refer to package read me and use it accordingly |
Beta Was this translation helpful? Give feedback.
-
@ankurk91 I'm sorry could you elaborate a little bit on what part is wrong? I read through the documentation prior to opening an issue. The only thing I can see is that I'm not using |
Beta Was this translation helpful? Give feedback.
-
You are mutating the data property via event, and binding the same property. The Flat picker component is watching the value prop and emit input event, which might be causing the infinite loop. What sre you trying to achieve, why can't you use the component directly. Why do need another wrapper component? |
Beta Was this translation helpful? Give feedback.
-
Isn't that the standard way I'm using a wrapper component because I have more code in reality, I only provided a minimal example as per the issue template. My component automatically handles adding a |
Beta Was this translation helpful? Give feedback.
-
@karllinden Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
Thanks, it actually looks like the issue only occurs when emitting a date object. If I emit a string then it works fine but if I convert it to a date object first then it loops. I would much prefer to emit a date object, is that possible? I've updated your example with date objects to show the crash. |
Beta Was this translation helpful? Give feedback.
-
This has been discussed many times, it is not possible for now. |
Beta Was this translation helpful? Give feedback.
-
Hi @ankurk91, thanks for you work on the wrapper first and foremost 🙏 I've ran into this today as well. It's a pretty common use case to wrap a component in a wrapper: either to provide custom markup and styles or extra logic. Composition and "controlled components" is an encouraged pattern in vue community. Anyways, as @KeironLowe, In my case I just wanted to keep the
Since flatpickr always returns as <template>
<div class="my-extra-stuff">
<flat-pickr
:value="value"
@input="onInput"
/>
</div>
</template>
<script>
import flatPickr from 'vue-flatpickr-component'
export default {
name: 'WrappedFlatPickr',
props: ['value'],
componets: {
'flat-pickr': flatPickrComponent
},
data: () => ({
originalInputType: null
}),
created() {
// for testing purposes only, please don't do this
this.originalInputType = Array.isArray(this.value) ? 'array' : 'string'
},
methods: {
onInput(dateStr) {
const parsedValue = this.originalInputType === 'array'
? dateStr.split()
: dateStr
console.log('wrapped:inputEvt')
this.$emit('input', parsedValue)
}
}
}
<script> <!-- on parent, and yes this is dummy example -->
<wrapped-flat-pickr v-model="someModelArrayWithDate" /> This is how The problemI don't know vue-flatpickr-component/src/component.js Lines 179 to 185 in 8a5e434 When you're notifying watch: {
value(newValue) {
// will never stop if `newValue` is an `Array` and this.$el.value is a `string` (you won't notice at the beginning because this watcher is only called after first update)
if (newValue === this.$el.value) return;
} watch: {
value(newValue, prevValue) {
// will also not work because objects are not strict equals
if (newValue === prevValue) return;
} Proposed solutions:
watch: {
value(newValue, prevValue) {
// will prevent the loop.
if (JSON.stringify(newValue) === JSON.stringify(prevValue)) return;
}
value(newValue, prevValue) {
// Prevent updates if v-model value is same as input's current value
if (newValue === this.$el.value) return;
// Make sure we have a flatpickr instance
this.fp &&
// Notify flatpickr instance that there is a change in value
// seeting this to true (emit events) will cause infinite loop on parent
// components wrapping and manually binding events.
this.fp.setDate(newValue, false);
},
}, Reproduction exampleI've cloned your repo with some examples to help putting all this into context.
Sry for the long post, i've tried my best to be clear on my explanation, but as a non-native english speaker, that can be exceptionally hard to do in short way. ✌️ |
Beta Was this translation helpful? Give feedback.
-
Thanks for the write up, and possible solution. I have gone through this issue initially when i was creating this component. I am happy to implement and go with your approach. But i have some questions that needs clarification.
I will invest some time on weekends to implement your solution. |
Beta Was this translation helpful? Give feedback.
-
@ankurk91 thanks for looking at it, i'll do my best to try to clarify your points in order.
I really hope that this was helpful, if you want I can review your PR when ready or make one myself. Cheers ☮️ |
Beta Was this translation helpful? Give feedback.
-
hit this issue as well is there any work around? for quick fix or there another version release to fix this issue? |
Beta Was this translation helpful? Give feedback.
-
<template>
<flat-pickr
v-model="clone_value"
@input="onInput"
:config="config"
/>
</template>
<script>
import flatPickr from 'vue-flatpickr-component';
import 'flatpickr/dist/flatpickr.css';
export default {
name: 'FlatPickrWrapper',
components: {
flatPickr
},
props: {
value: {
required: true,
default: ''
},
config: {
type: Object,
default: () => ({})
}
},
data() {
return {
clone_value: new Date(this.value),
}
},
watch: {
// value(val) {
// this.clone_value = val instanceof Date ? val.toString() : val;
// }
},
methods: {
onInput(value) {
this.$emit('input', new Date(value))
}
}
}
</script> this is my quick fix hahaha :) just clone the value and done. but still you need fix this issue
voila!! |
Beta Was this translation helpful? Give feedback.
-
@renatodeleao Checkout to Notice that
|
Beta Was this translation helpful? Give feedback.
-
Hey @ankurk91 sry for the delay in the response.
A question though, relative to the watcher: value(newValue) {
if (JSON.stringify(newValue) === JSON.stringify(this.fp.selectedDates)) return;
} Any particular reason why you use Cheers ☮️ |
Beta Was this translation helpful? Give feedback.
-
I'm submitting a ... (check one with "x")
Tell about your platform
Current behavior
An infinite loop occurs and crashes the browser when selecting a date when using
:value
and@input
instead ofv-model
. I use flatpickr inside another component hence we can't use v-model.Expected behavior
The data is updated without a loop.
Minimal reproduction of the problem with instructions
Component Usage
DatePicker Component
Beta Was this translation helpful? Give feedback.
All reactions