vue.jsyandex-api

VueJS async detect language with Yandex Translate API


I'm experimenting with Yandex Translate API using VueJS to detect the language of the entered text asynchronously.

Everything works right. But there is a problem; log returns for each letter I write.

For example, when I write 'hello': api predicts the language of each of the words 'h', 'he', 'hel', 'hell', 'hello' and turns 5 log. What I want is that the API returns 1 log for the word 'hello' asynchronously after the timeout. It checks it for every letter. How can I fix it?

Html part of TranslateForm.vue

<template>
    <textarea v-model="translateText" cols="30" rows="5" class="form-control" placeholder="Translate something."></textarea>
</template>

Script part of TranslateForm.vue

import axios from 'axios'
export default {
  name: 'TranslateForm',
  data () {
    return {
      translateText: '',
      apiKey: '********',
      detectLangApiUrl: '***********'
    }
  },
  watch: {
      translateText (value) {
        if (value) {
          axios.post(this.detectLangApiUrl + '?key=' + this.apiKey + '&text=' + value)
            .then(response => {
              console.log(response)
            }).catch(e => console.log(e))
        }
      }
   }
}

Solution

  • The problem is that you are calling the API every time translateText is updated (after each key press). If you don't want to simply have a button, one way to do that would be to listen to the blur event (when the user focuses out of the textarea) and call the method then:

    <template>
        <textarea v-model="translateText" @blur="translate" cols="30" rows="5" class="form-control" placeholder="Translate something."></textarea>
    </template>
    
    <script>
    import axios from 'axios'
    export default {
      name: 'TranslateForm',
      data () {
        return {
          translateText: '',
          apiKey: '********',
          detectLangApiUrl: '***********'
        }
      },
      methods: {
        translate () {
           if (this.translateText) {
              axios.post(this.detectLangApiUrl + '?key=' + this.apiKey + '&text=' + this.translateText)
                .then(response => {
                  console.log(response)
                }).catch(e => console.log(e))
            }
        }
      }
    }
    </script>
    

    You could also limit the number of times the method is called, using a debounce function. For example, to call translate only once every second:

    <script>
    import axios from 'axios'
    import { debounce } from 'lodash'
    
    export default {
      name: 'TranslateForm',
      data () {
        return {
          translateText: '',
          apiKey: '********',
          detectLangApiUrl: '***********',
          debouncedTranslate: debounce(() => {
            axios.post(this.detectLangApiUrl + '?key=' + this.apiKey + '&text=' + this.translateText)
                .then(response => {
                  console.log(response)
                }).catch(e => console.log(e))
          }, 1000)
        }
      },
      watch: {
          translateText (value) {
            if (value) {
              this.debouncedTranslate()
            }
          }
       }
    }
    </script>