Search code examples
javascriptmongodbexpressgridfsgridfs-stream

Saving audio data using GridFS


This code (see below) is only working partly and I need some help to fix it.

The function saveAudioToGridFS() is supposed to return a file ID to its calling function.

I can check that the value to be returned is properly computed (through the console.log(s)).

But due to some synchronization problems or something similar it is not passed to the calling side.

How can I fix this ? Any relevant tip is going to be welcome.

function saveAudioToGridFS(audioBlob) {
  const gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db),
        writeStream = gridFSBucket.openUploadStream(getAudioName())

  // In the code below, writeStream.id.toString() is precisely what
  // should be returned to the calling function.
  writeStream.on('close', (file) => {
    console.log("saveAudioToGridFS.close-block")
    console.log("ID=",writeStream.id.toString())
    resolve(writeStream.id.toString())
  });

  writeStream.on('finish', (file) => {
    console.log("saveAudioToGridFS.finish-block")
    console.log("ID=",writeStream.id.toString())
    resolve(writeStream.id.toString())
  });

  writeStream.on('error', (error) => {
    console.log("saveAudioToGridFS.error-block")
    reject(error);
  });

  console.log("TRACE 1 : before createReadStream.")
  streamifier.createReadStream(audioBlob).
   pipe(writeStream)
  console.log("TRACE 2 : after createReadStream.")
} /* End of saveAudioToGridFS */


server.post('/upload', async (req, res) => {
  try {
    if (!req.body.audio) {
      return res.status(400).json({message: 'No audio data uploaded.'});
    }

    console.log("Before call to saveAudioToGridFS")
    const audioBuffer = Buffer.from(req.body.audio, 'base64'),
          fileId = saveAudioToGridFS(audioBuffer);

    console.log("fileId=",fileId) // The expected value is missing here.
    // Consequently the value of fileId is missing in the following code.

    // Create a new record object
    const newRec = new AppCollectn({
      channelID:req.body.channel,
      voiceRecordID:fileId,
      timeStamp: new Date().getTime()
    });

    // Insert the record in our MongoDB database
    await newRec.save();

    .....
    res.json({fileId});
  } catch (error) {
    console.error(error);
    res.status(500).json({
      message: 'An error occurred during upload.',
      error: JSON.stringify(error)
    });
  }
});

Solution

  • Turn your saveAudioToGridFS into an asynchronous function that returns a promise.

    Here is the code

    function saveAudioToGridFS(audioBlob) {
      return new Promise((resolve, reject) => {
        const gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db),
          writeStream = gridFSBucket.openUploadStream(getAudioName())
    
        writeStream.on('close', (file) => {
          console.log("saveAudioToGridFS.close-block")
          console.log("ID=",writeStream.id.toString())
          resolve(writeStream.id.toString()) 
        });
    
       writeStream.on('finish', (file) => {
         console.log("saveAudioToGridFS.finish-block")
         console.log("ID=",writeStream.id.toString())
         resolve(writeStream.id.toString()) 
       });
    
       writeStream.on('error', (error) => {
         console.log("saveAudioToGridFS.error-block")
         reject(error); 
      });
    
       console.log("TRACE 1 : before createReadStream.")
       streamifier.createReadStream(audioBlob).
        pipe(writeStream)
       console.log("TRACE 2 : after createReadStream.")
     });
    
    }
    
    
    
    
    server.post('/upload', async (req, res) => {
      try {
        if (!req.body.audio) {
          return res.status(400).json({message: 'No audio data uploaded.'});
        }
    
        console.log("Before call to saveAudioToGridFS")
        const audioBuffer = Buffer.from(req.body.audio, 'base64');
    
      
       const fileId = await saveAudioToGridFS(audioBuffer); 
    
       console.log("fileId=",filed)
    
       const newRec = new AppCollectn({
         channelID:req.body.channel,
         voiceRecordID:fileId,
         timeStamp: new Date().getTime()
       });
    
       // Insert the record in our MongoDB database
       await newRec.save();
    
       .....
       res.json({fileId});
    
    
      } catch (error) {
        console.error(error);
        res.status(500).json({
         message: 'An error occurred during upload.',
         error: JSON.stringify(error)
       });
      }
    });