Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when using startListening #4

Closed
kejtizuki opened this issue Dec 1, 2017 · 13 comments
Closed

Error when using startListening #4

kejtizuki opened this issue Dec 1, 2017 · 13 comments

Comments

@kejtizuki
Copy link

kejtizuki commented Dec 1, 2017

Hi,
I've added this in my code:

const propTypes = {
// Props injected by SpeechRecognition
  transcript: PropTypes.string,
  resetTranscript: PropTypes.func,
  startListening: PropTypes.func,
  browserSupportsSpeechRecognition: PropTypes.bool
}

I want to create the button which will enable speech recognition on click. I tried using the 'startListening' function but it's not working for me. I'm getting the error cannot read property 'setState' of undefined at startListening. Could you help me with that? I'm new to react so maybe it's just my mistake...

@JamesBrill
Copy link
Owner

I'd be happy to help. Can you share the code where you are using startListening?

@kejtizuki
Copy link
Author

render (){
    const { transcript, resetTranscript, startListening, browserSupportsSpeechRecognition } = this.props;
    if (!browserSupportsSpeechRecognition) {
      return (<p>Your browser doesn't allow speech recognition</p>)
    }
    return(
      <div className="container">
        <button className="btnStart" onClick={startListening}>
          <img src="../../assets/microphone.svg" className="icon"/>
        </button>
        <input className="speechTranscript" onChange={this.handleChange.bind(this)} value={transcript}/>
        <div className="actions">
          <button className="btn">Stop</button>
          <button className="btn" onClick={resetTranscript}>Reset</button>
        </div>
      </div>
    )
  }

I tried doing something like this

@JamesBrill
Copy link
Owner

I have made a component that renders virtually the same as yours, but was unable to reproduce this error. A few more questions to help me determine the issue:

  • What is your code for using the SpeechRecognition component itself? In other words, how are you using it to wrap your own component?
  • What is the code in your handleChange method? Are you using setState in there?
  • When does the error occur? When the component is first rendered or when you click on your microphone button? Or on some other action?
  • What is the exact error and stack trace?
  • Which browser are you using?
  • What happens if you try to use the following component?
import React, { PropTypes, Component } from 'react'
import SpeechRecognition from 'react-speech-recognition'

const propTypes = {
  // Props injected by SpeechRecognition
  transcript: PropTypes.string,
  startListening: PropTypes.func,
  stopListening: PropTypes.func,
  browserSupportsSpeechRecognition: PropTypes.bool
}

class Dictaphone extends Component {
  render() {
    const {
      transcript,
      startListening,
      stopListening,
      browserSupportsSpeechRecognition
    } = this.props

    if (!browserSupportsSpeechRecognition) {
      return null
    }

    return (
      <div>
        <button onClick={stopListening}>Stop</button>
        <button onClick={startListening}>Start</button>
        <span>
          {transcript}
        </span>
      </div>
    )
  }
}

Dictaphone.propTypes = propTypes

export default SpeechRecognition(Dictaphone)

@JamesBrill
Copy link
Owner

Were you able to resolve this, @kejtizuki?

@kejtizuki
Copy link
Author

kejtizuki commented Jan 8, 2018

Yeah actually if I use it without defining options it works, but if I want to use it with options:

const options = {
  lang : 'en-US',
  autoStart: false
}

export default SpeechRecognition(options)(Dictaphone)

Than it gives me this error. Sorry for late response but I just wasn't working on this earlier..

@kejtizuki
Copy link
Author

And to answer your questions. Yes, I'm using setState in handleChange method.
The error occurs when I click on button that should activate startListening method.
Exact error looks like this:

bundle.js:61568 Uncaught TypeError: Cannot read property 'setState' of undefined
at startListening (bundle.js:61568)
at bundle.js:8912
at HTMLUnknownElement.boundFunc (bundle.js:16228)
at Object.ReactErrorUtils.invokeGuardedCallback (bundle.js:16234)
at executeDispatch (bundle.js:16016)
at Object.executeDispatchesInOrder (bundle.js:16039)
at executeDispatchesAndRelease (bundle.js:15694)
at executeDispatchesAndReleaseTopLevel (bundle.js:15705)
at Array.forEach ()
at forEachAccumulated (bundle.js:16335)

@JamesBrill
Copy link
Owner

I haven't been able to reproduce this so far. It's especially baffling that the error only occurs when passing in options. On that note, I can point out one thing you can fix. The only option that does anything is autoStart. If you want to change the lang, you can do this by taking the injected recognition object and setting the lang on it like so:

recognition.lang = 'en-US'

The error you see occurs when a class method isn't bound to any context (this is why you need to do things like this.foo.bind(this). If you're passing in my startListening as your onClick callback, then that error seems to be coming from the SpeechRecognition library. The startListening method does indeed call this.setState. However, I'm not sure why this is undefined in this case - I use a library called autobind that binds that method to the component's context.

Perhaps autobind gets confused about the component to bind to when higher-order components are involved. Or perhaps I've missed something really obvious. I'll keep investigating!

If I run out of ideas, I'll try replacing my autobind methods with arrow functions.

@kejtizuki
Copy link
Author

kejtizuki commented Jan 10, 2018

Sorry I think I confused it a bit. I also get this error when I use the code that you put above, however (using the code from above from your comment) I don't get the error when I click on start but now I get it in stopListening.

Uncaught TypeError: Cannot read property 'setState' of undefined
at stopListening (SpeechRecognition.js?fb07:188)
at makeAssimilatePrototype.js?c7d8:15
at HTMLUnknownElement.boundFunc (ReactErrorUtils.js?dc41:63)
at Object.ReactErrorUtils.invokeGuardedCallback (ReactErrorUtils.js?dc41:69)
at executeDispatch (EventPluginUtils.js?5d8c:83)
at Object.executeDispatchesInOrder (EventPluginUtils.js?5d8c:106)
at executeDispatchesAndRelease (EventPluginHub.js?0f32:41)
at executeDispatchesAndReleaseTopLevel (EventPluginHub.js?0f32:52)
at Array.forEach ()
at forEachAccumulated (forEachAccumulated.js?e2c3:22)

If I use the same code with options I'm getting an error about startListening.
And also if I try to use resetTranscript I;m getting the following error:

Uncaught TypeError: Cannot read property 'disconnect' of undefined
at resetTranscript (SpeechRecognition.js?fb07:161)
at makeAssimilatePrototype.js?c7d8:15
at HTMLUnknownElement.boundFunc (ReactErrorUtils.js?dc41:63)
at Object.ReactErrorUtils.invokeGuardedCallback (ReactErrorUtils.js?dc41:69)
at executeDispatch (EventPluginUtils.js?5d8c:83)
at Object.executeDispatchesInOrder (EventPluginUtils.js?5d8c:106)
at executeDispatchesAndRelease (EventPluginHub.js?0f32:41)
at executeDispatchesAndReleaseTopLevel (EventPluginHub.js?0f32:52)
at Array.forEach ()
at forEachAccumulated (forEachAccumulated.js?e2c3:22)
resetTranscript @ SpeechRecognition.js?fb07:161
(anonymous) @ makeAssimilatePrototype.js?c7d8:15
boundFunc @ ReactErrorUtils.js?dc41:63
ReactErrorUtils.invokeGuardedCallback @ ReactErrorUtils.js?dc41:69
executeDispatch @ EventPluginUtils.js?5d8c:83
executeDispatchesInOrder @ EventPluginUtils.js?5d8c:106
executeDispatchesAndRelease @ EventPluginHub.js?0f32:41
executeDispatchesAndReleaseTopLevel @ EventPluginHub.js?0f32:52
forEachAccumulated @ forEachAccumulated.js?e2c3:22
processEventQueue @ EventPluginHub.js?0f32:252
runEventQueueInBatch @ ReactEventEmitterMixin.js?91f8:15
handleTopLevel @ ReactEventEmitterMixin.js?91f8:25
handleTopLevelImpl @ ReactEventListener.js?944f:70
perform @ Transaction.js?f15f:141
batchedUpdates @ ReactDefaultBatchingStrategy.js?e9be:60
batchedUpdates @ ReactUpdates.js?8e6b:95
dispatchEvent @ ReactEventListener.js?944f:145

@JamesBrill
Copy link
Owner

I'm still unable to reproduce this. I can see that there's a context binding problem within the SpeechRecognition component, but can't fathom what's causing it.

Are you able to share the list of devDependencies in your package.json file? This will help me reproduce your build setup.

Don't worry, I'm not going to give up just yet! :)

@lorantgulyas
Copy link

Hi,
I'm working on this project with @kejtizuki , I also looked into the error, it was quite mysterious. I spent some time with debugging with no success, then I created a new project with one component only. Same code in our part, same import from your npm package and there was no error. Then I started looking at version differences between my two projects and your package, just checked the main parts (react 15.4.0 at our project, 15.4.1 in yours, webpack 1.13.2 in our project, 1.14.0 at yours, babel-core 6.17.0 at ours, 6.21.0 at yours). After these steps I checked your src code, and I though what would happen if I'll just create a separate js file in our project containing your code. I changed the @autobind-s because we are using ES6 and now everything works fine. However I still don't know what went wrong with the npm-package-import method. So the problem we had can be considered as solved, thanks for all the help :)

@lorantgulyas
Copy link

Hi again,
Just after I send the previous comment I remembered something... I checked my last theory, created a very similar project to ours, same boilerplate and after importing your package and using it in a simple component the error appeared again. I think it is connected to webpack dev server. Below I included the boilerplate we started with, I used this and a simple google speech component in the App.jsx when reproducing the error.

https://github.com/takanabe/react-redux-material_ui-boilerplate

Hope it helps in the debugging process.

@JamesBrill
Copy link
Owner

Thank you for providing this information and being so patient!

The reason I asked for your devDependencies is because of a bug between the autobind decorator I use from core-decorators and react-hot-loader - issues similar to the ones you experienced occur when old versions of react-hot-loader are used. The issue is discussed here.

The boilerplate you shared includes that older version of the hot loader, so I would wager that that's the cause. Try upgrading react-hot-loader to 2.0.0-alpha-4 or later.

On my side, I should really stop depending on core-decorators and autobind - when I have some time, I'll replace it with some old-school binds.

@lorantgulyas
Copy link

Thank you. I updated react-hot-loader and there is no error anymore 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants