0

From the highest level, I'm trying to pass a Blob to a function that will transcribe the data and return the transcript. I'm struggling to get the async parts of the process lined up correctly. Any insight would be appreciated.

The two files I'm working with are below. In the record.jsx file, I'm calling the googleTranscribe function ( that is located in the second file ) to do the transcription work and hopefully return the transcript. This is where I'm running into the problem - I can get the transcript but cannot return it as a value. I know I'm doing something wrong with async / await / promises, I just can't quite figure out what I'm doing wrong.

record.jsx

import React from "react";
import googleTranscribe from '../../functions/googletranscribe.js';
const audioType = 'audio/wav';

class Record extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      recording: false,
      audioUrl: '',
      audios: [],
    };
  }

   componentDidMount() {

    const player = document.getElementById('player');
    const stopButton = document.getElementById('stop');
    const startButton = document.getElementById('start');

    const initalizeRecorder = function(stream) {

      if (window.URL) {
        player.srcObject = stream;
      } else {
        player.src = stream;
      }

      const options = {mimeType: 'audio/webm'};
      let recordedChunks = [];
      const mediaRecorder = new MediaRecorder(stream, options);

      mediaRecorder.addEventListener('dataavailable', function(e) {
        if (e.data.size > 0) {
          recordedChunks.push(e.data);
        }
      });

      mediaRecorder.addEventListener('stop', function() {
        const audioData = recordedChunks;

        // convert saved chunks to blob
        const blob = new Blob(audioData, {type: audioType});

        // generate video url from blob
        const audioUrl = window.URL.createObjectURL(blob);
        
        googleTranscribe(blob)
          .then((response) => {
            console.log('transcript: ' + response);
          }).catch((error) => {
            console.log('error: ' + error);
          });

      });

      startButton.addEventListener('click', function() {
        mediaRecorder.start(1000);
      });

      stopButton.addEventListener('click', function() {
        mediaRecorder.stop();
      });

    };

    navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then(initalizeRecorder);
  
  render() {
    
    return (
      <section>
        <button id="start">Record</button>
        <button id='stop'>Stop</button>
      </section>
    );
  }
}

export default Record;

googletranscribe.jsx

import axios from 'axios';

const googleTranscribe = async (audioBlob) => {

  const apiUrl = "http://localhost:8080/api/google-transcribe";
  
  const url = encodeURI(apiUrl); 

  // Send blob to the server
  const formData = new FormData();
  formData.append('file', audioBlob, 'blobby.wav');
  
  var config = {
    method: 'post',
    url: url,
    headers: { "Content-Type": "multipart/form-data" },
    data : formData,
  };

  axios(config)
  .then(function (res) {
    console.log('AXIOS success');
    console.log(res);
    return res.data;
  })
  .catch(function (err) {
    console.log('AXIOS error');
    console.log(err.message);
    return 'AXIOS we found an error';
  });

}

export default googleTranscribe;
SuperStormer
  • 4,997
  • 5
  • 25
  • 35
John Goodman
  • 1,058
  • 12
  • 14
  • 1
    Probably a dup of https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call. – jfriend00 Jun 06 '21 at 01:43
  • You're not using `await` instead of `.then()` despite trying to use `async`/`await`. Therefore your `return` doesn't work – Bergi Jun 06 '21 at 01:43
  • 1
    You should `return axios(config).then...`, which returns the promise. – Matt U Jun 06 '21 at 01:48

2 Answers2

1

The problem is in the second file. The line with your Axios should be modified as such:

return axios(config)
  .then(function (res) {
    console.log('AXIOS success');
    console.log(res);
    return res.data;
  })
...

The axios call internally returns the value, but you never return it from googletranscribe

Ethan Snow
  • 447
  • 2
  • 10
  • This might help. But remember, in order to "get" the return value `res` you need to wait for the async function `googleTranscribe()` to resolve, like in: `googleTranscribe(audioBlob).then(res=>do_something_with(res));`. – Carsten Massmann Jun 06 '21 at 05:59
1

Let me get you some context on async-await The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. The best place for more information would be Here

Dharman
  • 30,962
  • 25
  • 85
  • 135