Segfaulter
Segfaulter

Reputation: 73

Return Variable in Node Module Call Back

I'm using this NPM package to get the CSV output of table from an access database.

I have my function structured as follows:

function createDB(mdbfile){
  var rawDB = mdb(mdbfile);
  var db = {}
  rawDB.tables(function(err, table){
    table.forEach(function(item){
      var rawTable = null;
      rawDB.toCSV(item, function(err, csv){
        rawTable = csv; //Doesn't work
      });
      console.log(rawTable); //Always null :(
      
      var newTable = Do stuff with CSV;
      db.item = newTable;
    });
  });

  return db
}

I'm sure this is some scoping issue but I'm new to node and don't know how to search for this properly. From what I can tell the module is synchronous but the scope doesn't work.

Any help would be appreciated! Unfortunately a client I have MUST use access DB file and I'm just trying to make this work.

Upvotes: 0

Views: 60

Answers (1)

akz
akz

Reputation: 51

The scoping looks fine, but the toCsv function does not look synchronous. You can double check the source code: https://github.com/maxogden/node-mdb/blob/master/index.js. So, you would try to print out rawTable before the toCsv callback is called.

I would also add proper error handling within both callbacks to see whether you are getting any errors.

EDIT:

Since your createDB function makes asynchronous calls, it should take a callback. The code below is an example that could possibly work for your case.

// look into the async module, specifically forEach
const asyncForEach = require('async/forEach');

function createDB(mdbfile, next ){
  var rawDB = mdb(mdbfile);
  var db = {}
  rawDB.tables(function(err, table){

    if( err ) return next(err);     

    asyncForEach(
        table,
        function(item, cb){
            rawDB.toCSV(item, ( err, csv )=>{
                if( err ) return cb( err );
                // this processing can be done here or in the callback to asynForEach
                var newTable = Do stuff with CSV;
                db.item = newTable;
                cb(null, csv);
            };
        },
        function(err, csvs){
            // csvs can be processed and added to db here as well
            if ( err ) return next( err );
            return next( null, db );
        } );
   } );
}

You would then have to provide a callback to createDB when you call it:

createDB( mdbFile , ( err, db )=>{
    if( err ) return err;
    // use db e.g. res.send( db )
}

Or you could look into how to accomplish this with promises.

Upvotes: 1

Related Questions