0

I have a Vue component with an input with which I used v-model. Theorically it works fine but in practice, it works really bad, if I type too quickly, the input value is broken (for example, typing azertyuiop will result with auip).
I can't type slowly as the input will be filled by scanning barcodes (real quick).

Each time the user types, it makes a request using axios, and I guess that's the source of the issue but I have no idea what I can do about it.

How could I avoid this issue ?

Here is my Ordeline.vue:

<template>
    <div class="field">
        <label class="label">{{ fullname }}</label>
        <div class="control">
            <input
                    :class="'input' + (value.valid ? '' : ' is-danger')"
                    v-model="modelValue"
                    type="text">
        </div>
        <p v-if="error !== null" class="help is-danger">
            <span class="tag is-danger">ERREUR</span>
            {{ error }}
        </p>
    </div>
</template>

<script>
import api from '../axios-wrapper';

export default {
    name: "orderline",
    props: {
        value: {required: true},
        apiTarget: {required: true}
    },
    computed: {
        modelValue: {
            get() {
                return this.value.imei;
            },
            set(val) {
                this.validate(val);
            }
        },
        fullname () {
            return this.value.title + ' ' + this.value.grade_name;
            // return this.value.make_name + ' ' + this.value.color_name + ' ' + this.value.expected_memory + 'Go ' + this.value.grade_name;
        }
    },
    data () {
        return {
            error: null
        }
    },
    methods: {
        validate (val) {
            api
                .post(this.apiTarget, {
                    imei: val,
                    make_id: this.value.expected_make,
                    make_name: this.value.make_name,
                    color_id: this.value.expected_color,
                    color_name: this.value.color_name,
                    memory: this.value.expected_memory,
                    grade_id: this.value.expected_grade,
                    grade_name: this.value.grade_name,
                })
                .then(response => {
                    this.error = null;
                    let clone = this.value;
                    clone.imei = val;
                    clone.valid = true;
                    this.$emit('input', clone);
                })
                .catch(error => {
                    this.error = error.response.data.message;
                    let clone = this.value;
                    clone.imei = val;
                    clone.valid = false;
                    this.$emit('input', clone);
                })
            ;
        }
    },
    mounted() {
        this.validate(this.modelValue);
    }
}
</script>
AymDev
  • 6,626
  • 4
  • 29
  • 52
  • Do you really need to make an HTTP request on every change? Isn't it better to validate the whole barcode by adding modifier `v-model.lazy` on input? – Igor Aug 27 '19 at 10:49
  • @Igor I don't need to make an HTTP request on every change. I did not know about `v-model.lazy`, I will try it. I suddenly remembered [this part of the documentation](https://vuejs.org/v2/guide/computed.html#Watchers), do you know which one would be better ? I guess I'm asking a stupid question but I'm not a pro JS dev.. – AymDev Aug 27 '19 at 11:04
  • @Igor `v-model.lazy` apparently needs the user to click elsewhere of the input to send the request, this would not fit my needs :-/ – AymDev Aug 27 '19 at 11:47
  • does `imei` value has some fixed length? You may send the request only if it's length is equal to expected, like: `if (val.length === 12) api.post(...` – Igor Aug 27 '19 at 12:31
  • @Igor it should have a fixed length of 15 numeric characters but some devices have a different format. – AymDev Aug 27 '19 at 12:55
  • I finally solved my issue with [this question](https://stackoverflow.com/questions/42199956/how-to-implement-debounce-in-vue2) did not find it earlier because I did not have *debounce* in my vocabulary. – AymDev Aug 27 '19 at 13:15

0 Answers0