4

I'm using cordova's speech recognition plugin where after user click's on speech button startRecognition is triggered but if after 10000ms if user does not speaks anything then the stopListening() function should be triggered and this goes on continuously unless the user says exit.

I'm using setTimeout wrapped inside a promise and when that promise is resolved then i'm resolving the promise which is triggering the cordova plugin for speech recognition

This code will continously run speech recognition unless user says exit.

  listenMsgAndReplyRepeat() {
    const self = this;
    this.listenMsg().then(res => {
      alert('got result ' + res);
      if (res === 'Exit') {
        self.exitFromApp();
      } else if (res === 'Success') {
        self.listenMsgAndReplyRepeat();
      } else if (res === 'Stopped') {
        alert('the speech recognition was stopped');
        self.botReply('Hello? Do you Want me to Exit?');
        self.listenMsgAndReplyRepeat();
      } else {
        self.botReply('Some error occured will detecting speech');
      }
    });
  }

This code is the one which starts speech recognition

listenMsg() {
    const self = this;
    // Verify if recognition is available
    return new Promise(function(resolve, reject) {
      self
        .isRecognitionAvailable()
        .then(function(available) {
          if (available) {
            return window.plugins.speechRecognition.hasPermission();
          }
        })
        .then(function(hasPermission) {
          function startRecognition() {
            self.speakPopUp = true;
            return self
              .startRecognition({
                language: 'en-US',
                showPopup: false,
                matches: 2
                // showPartial: true
              })
              .then(function(result) {
                clearTimeout(self.stopListen);
                self.speakPopUp = false;
                if (result[0] === 'exit') {
                    resolve('Exit'); //working
                }
                self.botReply(result[0]).then(res => {
                  resolve('Success'); //working
                });
              })
              .catch(function(err) {
                reject('Error');
              });
          }
          if (!hasPermission) {
            self
              .requestPermission()
              .then(function() {
                self.stopSpeech().then(res => {
                  self.speakPopUp = false;
                  resolve('Stopped');  //this resolve is not working
                });
                startRecognition();
              })
              .catch(function(err) {
                console.error('Cannot get permission', err);
                reject('Error');
              });
          } else {
            self.stopSpeech().then(res => {
              self.speakPopUp = false;
              resolve('Stopped');  //this resolve is not working
            });
            startRecognition();
          }
        })
        .catch(function(err) {
          console.error(err);
          reject('Error');
        });
    });
  }

The resolve inside local function startRecognition is working but the one inside the if else condition is not working

Here is the stopRecognition code

  stopSpeech() {
    const self = this;
    return new Promise(function(resolve, reject) {
      self.stopListen = setTimeout(() => {
        self.stopListening().then(res => {
          clearTimeout(self.stopListen);
          resolve('stopped');
        });
      }, 10000);
    });
  }

The resolve inside setTimeOut is working.

I'm assigning setTimeOut to a variable because if the user speaks i have to clear it so that stopListening is not triggered.

4
  • You are basically wrapping a lot of async calls inside one promise resolve. Since you are only handling one resolve (in your new Promise), you will resolve the promise when resolve is called. startRecognition probably finishes before stopSpeech, thus resolving your main-promise before the voice .then finishes? Commented Jun 3, 2019 at 6:29
  • Just as a tip, even if you are getting a promise, always use observables. Convert your promises to observables. it's good practice Commented Jun 3, 2019 at 6:33
  • @thsorens No..not always.It keeps running until the user speaks.If the user does not speak under 10000 ms then stopListening is triggered before it Commented Jun 3, 2019 at 6:38
  • Also if i remove setTimeOut then it is working Commented Jun 3, 2019 at 8:17

1 Answer 1

0

I was able to solve this issue by using Promise.all().I wrapped the timeout inside a promise and passed it into the promise array and after that i pushed the stopListening promise to it.

const promises = [];
promises.push(self.delay(10000));
promises.push(self.stopListening());
Promise.all(promises).then((res) => {
   self.speakPopUp = false;
   resolve('Stopped');
  });
  delay(t) {
    return new Promise(function(resolve) {
        setTimeout(resolve, t);
    });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.