0

I am trying to use the speech recognition instance and inside the success callback I am trying to use the speech term to call an api. The problem is that the success call back 'this' is being taken as the instance of speech recognition object and not the class instance.

Next I went through some of the solutions and copied the this instance into a that variable and called the functions. Now the function call is working but all the angular bindings are failing. The code snippet is as below:

 voiceSearch() {
    console.log('listening');

    if ("webkitSpeechRecognition" in window) {
      const vSearch = new webkitSpeechRecognition();
      vSearch.continuous = false;
      vSearch.interimresults = false;
      vSearch.lang = 'en-US';
      vSearch.start();
      let that = this;

      vSearch.onresult = function (e) {
        voiceHanlder.value = e.results[0][0].transcript;
        that.searchTerm = voiceHanlder.value;
        vSearch.stop();
        that.searchProducts(that.searchTerm); // unable to use this code without using that = this

      }

      vSearch.onerror = function (e) {
        console.log(e);
        vSearch.stop();
      }
    }
    else {
      console.log('Your browser does not support speech recognition');
    }
  }

     searchProducts(searchTerm: string) {
        this.searchMade = true;
        this.getProducts(searchTerm).subscribe(resp => {
          this.searchedProducts = resp['records'];
          this.searchValue = "Now showing the searched products";
          console.log(this.searchedProducts);
        })
      }

I changed the code to:

  vSearch.onresult ( (e) => {
    voiceHanlder.value = e.results[0][0].transcript;
    that.searchTerm = voiceHanlder.value;
    vSearch.stop();
    that.searchMade = true;
    that.searchCvsProducts(that.searchTerm);
    that.listeningOn = false;
    //voiceSearchForm.submit();
  })

But I am getting an error like vSearch.onResult is not a function.

Can we use a fat arrow operator to avoid the that = this code.

Kaizen Programmer
  • 3,798
  • 1
  • 14
  • 30
jack sparrow
  • 173
  • 1
  • 1
  • 9
  • 1
    It should be `vSearch.onresult = (e) => { ... }`. – ConnorsFan Jan 23 '19 at 22:13
  • 1
    Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – ConnorsFan Jan 23 '19 at 22:13
  • @connorsFan - I have been able to use the fat arrow as well as function.prototype.bind but now I am seeing an issue that angular is not updating it bindings after the call back immediately. It is however doing the same after I do another search. Any idea on the same. I can trigger the bind operations manually but that doesn't answer why they should not work in the first place. If I do not do the speech recognition then that works absolutely fine. – jack sparrow Jan 29 '19 at 14:41
  • Try wrapping the code in `NgZone.run(() => { ... })`, as suggested in [this answer](https://stackoverflow.com/a/36919459/1009922). – ConnorsFan Jan 29 '19 at 14:45

1 Answers1

0

You need to use na arrow function to capture the this context.

vSearch.onresult = (e) => {
        voiceHanlder.value = e.results[0][0].transcript;
        this.searchTerm = voiceHanlder.value;
        vSearch.stop();
        this.searchProducts(this.searchTerm);
}

I recommend you read the Functions chapter in the TypeScript Handbook it has good explanation how this works in functions.

Aleš Doganoc
  • 11,568
  • 24
  • 40