Creando una aplicación de reconocimiento de voz con Watson, React y Express
Parte 3. Integración con ReactJS
Este tutorial se encuentra divido en tres partes, cada una de las cuales se encuentra en los siguientes enlaces:
- Introducción, instalación de dependencias y configuración de backend
- Registro en IBM Watson, configuración de keys y claves, ejemplos de uso de la API
- Integración con ReactJS (Estamos aquí)
Simplificando la conexión al servidor
ReactJS viene con hot-reloading por default, esto nos permitirá compilar el código una vez detecta los cambios y refrescar el navegador para mostrarlos, pero al crear un servidor a parte, perdemos la posibilidad de conectarnos directamente con nuestra API, para simplificar un poco esa tarea, vamos a modificar un poco el archivo package.json
cambiando nuestros scripts de arranque, de la siguiente forma:
"scripts": {
"start:react": "react-scripts start",
"start:watson": "node server.js",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
Esto nos permite usar los comandos directamente en nuestra terminal:
// con npm
npm run start:react // para correr la aplicación con react
npm run start:watson // para correr el servidor de la API
// con yarn
yarn start:react // para correr la aplicación con react
yarn start:watson // para correr el servidor de la API
Ahora tenemos una forma más comoda de ejecutar ambos servidores, por supuesto que se puede hacer de una manera más sencilla con webpack, pero eso lo mostraré en otro tutorial.
Instalación de dependencias
Una de las cosas más importantes del desarrollo frontend es consumir API’s, en este caso la API que nos toca consumir es REST, ya que así lo creamos en nuestro servidor, por lo que nos ayudaremos de una tecnología muy importante para este fin, su nombre es axios y nos permite hacer peticiones asíncronas por medio de promesas.
Si gustas puedes checar la documentación en el siguiente enlace:
Vamos a agregar axios en nuestro proyecto:
// con npm
npm install --save axios
// con yarn
yarn add axios
También vamos a necesitar agregar una dependencia que nos permitirá actualizar las cabeceras (headers) de nuestra API y poder establecer conexiones desde fuentes diferentes a nuestra propia API, este dependencia se llama cors, escribimos en nuestra terminal lo siguiente:
// con npm
npm install --save cors
// con yarn
yarn add cors
Ahora simplemente tenemos que agregarlo a nuestra API, abrimos el archivo server.js
y escribimos lo siguiente:
// en la parte donde agregamos las dependencias
const cors = require('cors');// y antes de la línea
// app.use(express.static(__dirname, '/static'));
// Middlewares
app.use(cors());
Ahora ya podremos conectar nuestra API de forma correcta, corremos ambios servidores para probar y empezamos en React.
Abrimos localhost:3000
para probar que todo marche bien.
Integrando con ReactJS
Ahora abrimos el archivo src/App.jsx
y agregamos la dependencia, también vamos a agregar watson-speech para poder conectarnos a watson correctamente:
// Agregamos las siguientes líneas
import axios from 'axios';
import recognizeMicrophone from 'watson-speech/speech-to-text/recognize-microphone';
Vamos a cambiar nuestro componente puro a un componente de clase, esto nos permitirá utilizar el state de React para que podamos hacer las peticiones asíncronas sin problema:
Ahora nuestro componente se tiene que ver de la siguiente forma:
class App extends Component {
render() {
return (
<div>
<Navbar>
Watson Voice Recognition
</Navbar><div className="mdc-layout-grid">
<h2 className="mdc-typography--title">
To get started, edit <code>src/App.js</code> and save to reload.
</h2>
</div>
</div>
);
}
}
Eso nos permitirá generar un estado, ahora necesitamos uitlizar un botón que nos permita conectarnos a Watson, utilizando material-design creamos lo siguiente, de tal forma que nuestro componente quedará así:
<button
className="mdc-button mdc-button--raised"
onClick={this.onListenClick}
>
<i className="material-icons mdc-button__icon mdc-button__raised">mic</i>
Escuchar micrófono
</button>
<h1 className="mdc-typography--tite">
{this.state.text}
</h1>
Ahora necesitamos crear en nuestra aplicación el método onListenClick, en este caso es importante recalcar lo siguiente, aquí es donde haremos la conexión con Watson, entonces, para ser breves pondré el método completo:
onListenClick() {
axios.get('http://localhost:3002/api/speech-to-text/token')
.then((res) => {
const token = res.data;
const stream = recognizeMicrophone({
token,
objectMode: true,
extractResults: true,
format: false,
});stream.on('data', (data) => {
this.setState({ text: data.alternatives[0].transcript });
});stream.on('error', err => console.error(err));
});
}
Esto nos permite generar una petición asíncrona por medio de una promesa, una vez se obtiene los datos de la API.
Por la forma en la que funciona Javascript, necesitamos decirle que el elemento al que debe de responder es al botón, por lo que tenemos que agregar las siguientes líneas, asegurándonos también que agreguemos el state que queremos cambiar en ReactJS.
Por lo que en nuestro constructor vamos a agregar lo siguiente, justo debajo de la clase App.
constructor() {
super();
this.state = { text: '' };
this.onListenClick = this.onListenClick.bind(this);
}
Primero, les muestro como quedaría nuestro archivo App.jsx
:
Ahora ya podemos probar nuestra aplicación, simplemente haciendo click en el botón que creamos.
Recuerda que estamos corriendo el servidor con hot-reloading lo que nos permitirá ver los cambios de forma instántanea y sin necesidad de reinicar el servidor y el navegador.
Conclusión
Watson es una tecnología sorprendente, este tutorial sólo es para sentar las bases del uso de la inteligencia artificial en nuestros proyectos, en este caso con ReactJS y Express.
Pronto creamos una sección de tutoriales probando todo lo que Watson nos ofrece, no te pierdas nuestros próximos artículos y síguenos: