I am building a react-native app on windows and testing it on physical android device. The basic purpose of the app is to convert speech into text. I am using @react-native-voice library. First I created the app with
npx react-native init myapp
But on pressing the record button, it gives an error/warning of
cannot read properties of undefined( reading 'startSpeech)
Similarly I got the same warning for stopSpeech, destroySpeech etc.
After hectic search, I moved to expo-cli for creating the react-native app. But facing the same error again. Expo community expert says that expo has added the @react-native-voice into its expo-SDK > 41. You just have to add the plugins section into your app.json. plugin thing is explained in this stackOverflow post I have tried everything but nothing is working.
The code is attached below
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
TouchableHighlight,
} from 'react-native';
import Voice, {
SpeechRecognizedEvent,
SpeechResultsEvent,
SpeechErrorEvent,
} from '@react-native-voice/voice';
type Props = {};
type State = {
recognized: string;
pitch: string;
error: string;
end: string;
started: string;
results: string[];
partialResults: string[];
};
class App extends Component<Props, State> {
state = {
recognized: '',
pitch: '',
error: '',
end: '',
started: '',
results: [],
partialResults: [],
};
constructor(props: Props) {
super(props);
Voice.onSpeechStart = this.onSpeechStart.bind(this);
Voice.onSpeechRecognized = this.onSpeechRecognized;
Voice.onSpeechEnd = this.onSpeechEnd;
Voice.onSpeechError = this.onSpeechError;
Voice.onSpeechResults = this.onSpeechResults;
Voice.onSpeechPartialResults = this.onSpeechPartialResults;
Voice.onSpeechVolumeChanged = this.onSpeechVolumeChanged;
}
componentWillUnmount() {
Voice.destroy().then(Voice.removeAllListeners);
}
onSpeechStart = (e: any) => {
console.log('onSpeechStart: ', e);
this.setState({
started: '√',
});
};
onSpeechRecognized = (e: SpeechRecognizedEvent) => {
console.log('onSpeechRecognized: ', e);
this.setState({
recognized: '√',
});
};
onSpeechEnd = (e: any) => {
console.log('onSpeechEnd: ', e);
this.setState({
end: '√',
});
};
onSpeechError = (e: SpeechErrorEvent) => {
console.log('onSpeechError: ', e);
this.setState({
error: JSON.stringify(e.error),
});
};
onSpeechResults = (e: SpeechResultsEvent) => {
console.log('onSpeechResults: ', e);
this.setState({
results: e.value,
});
};
onSpeechPartialResults = (e: SpeechResultsEvent) => {
console.log('onSpeechPartialResults: ', e);
this.setState({
partialResults: e.value,
});
};
onSpeechVolumeChanged = (e: any) => {
console.log('onSpeechVolumeChanged: ', e);
this.setState({
pitch: e.value,
});
};
_startRecognizing = async () => {
this.setState({
recognized: '',
pitch: '',
error: '',
started: '',
results: [],
partialResults: [],
end: '',
});
try {
await Voice.start('en-US');
} catch (e) {
console.error(e);
}
};
_stopRecognizing = async () => {
try {
await Voice.stop();
} catch (e) {
console.error(e);
}
};
_cancelRecognizing = async () => {
try {
await Voice.cancel();
} catch (e) {
console.error(e);
}
};
_destroyRecognizer = async () => {
try {
await Voice.destroy();
} catch (e) {
console.error(e);
}
this.setState({
recognized: '',
pitch: '',
error: '',
started: '',
results: [],
partialResults: [],
end: '',
});
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native Voice!</Text>
<Text style={styles.instructions}>
Press the button and start speaking.
</Text>
<Text style={styles.stat}>{`Started: ${this.state.started}`}</Text>
<Text style={styles.stat}>{`Recognized: ${
this.state.recognized
}`}</Text>
<Text style={styles.stat}>{`Pitch: ${this.state.pitch}`}</Text>
<Text style={styles.stat}>{`Error: ${this.state.error}`}</Text>
<Text style={styles.stat}>Results</Text>
{this.state.results.map((result, index) => {
return (
<Text key={`result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
<Text style={styles.stat}>Partial Results</Text>
{this.state.partialResults.map((result, index) => {
return (
<Text key={`partial-result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
<Text style={styles.stat}>{`End: ${this.state.end}`}</Text>
<TouchableHighlight onPress={this._startRecognizing}>
<Image style={styles.button} source={require('./button.png')} />
</TouchableHighlight>
<TouchableHighlight onPress={this._stopRecognizing}>
<Text style={styles.action}>Stop Recognizing</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._cancelRecognizing}>
<Text style={styles.action}>Cancel</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._destroyRecognizer}>
<Text style={styles.action}>Destroy</Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: 50,
height: 50,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
action: {
textAlign: 'center',
color: '#0000FF',
marginVertical: 5,
fontWeight: 'bold',
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
stat: {
textAlign: 'center',
color: '#B0171F',
marginBottom: 1,
},
});
export default App;
Thank you in advance for the help :)