DragonBorn
DragonBorn

Reputation: 1809

Exporting a function declared inside asynchronous function

I have a file in which mongoose is setup

const keys = require('../chat/config/keys');
const mongoose = require('mongoose');
const dbURI = keys.mongoURI;
mongoose.connect(dbURI, { useNewUrlParser: true });
mongoose.set('debug', true);

let fetchVideo;

mongoose.connection.once('open', function () {
  console.log('Mongoose default connection open to ' + dbURI);

  let connectToDB = mongoose.connection.db;
  let videoChatDB = connectToDB.collection('videochat');

  fetchVideo = ({ id }) => {
    if (id !== '100') {
      videoChatDB.findOne({'studentID': parseInt(id)}).then((user) => {
        if (user) {
          console.log(user);
          return true;
        } else {
          console.log(user);
          return false;
        }
      });
    }
  }
});


module.exports = { fetchVideo };

And I am requiring that file inside my index.js file like so:

let db = require('./db');

In my index file I have a socket connection and I need to check the database when a new user comes.

socket.on('new-user', async (user) => {
  let checkAvail = await db.fetchVideo(user);
});

But I am getting this error:

TypeError: db.fetchVideo is not a function

I am guessing it is undefined since it is declared inside an asynchronous function.

How would I make this to work?

Upvotes: 0

Views: 24

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370859

Because the function is created asynchronously, one option is to export a Promise that resolves to fetchVideo function. Because mongoose.connection.once is callback-based, you'll have to transform it into a Promise.

If you want fetchVideo to resolve to something (rather than nothing), you also have to properly chain the findOne call with the promise chain; to fix that, return videoChatDB.findOne....

const fetchVideoProm = new Promise((res, rej) => {
  mongoose.connection.once('open', function () {
    console.log('Mongoose default connection open to ' + dbURI);

    let connectToDB = mongoose.connection.db;
    let videoChatDB = connectToDB.collection('videochat');

    const fetchVideo = ({ id }) => {
      if (id !== '100') {
        return videoChatDB.findOne({'studentID': parseInt(id)}).then((user) => {
          if (user) {
            console.log(user);
            return true;
          } else {
            console.log(user);
            return false;
          }
        });
      }
    }
    res(fetchVideo);
  });
});


module.exports = { fetchVideoProm };

Consume it by awaiting the creation of the fetchVideo function, and then calling it:

socket.on('new-user', async (user) => {
  const fetchVideo = await db.fetchVideoProm;
  const checkAvail = await fetchVideo(user);
});

Upvotes: 1

Related Questions