sourced-repo-mongo
sourced-repo-mongo copied to clipboard
Repository.getAll() fails with async/await / util.promisify
I tried using source-repo-mongo with Node 8 and async / await + util.promisify from Node 8.
This is my code:
"use strict";
const Entity = require("sourced").Entity;
const util = require("util");
const promisify = util.promisify;
const Repository = require("sourced-repo-mongo").Repository;
const mongo = require("sourced-repo-mongo/mongo");
function Customer() {
this.id = null;
this.name = null;
Entity.apply(this, arguments);
}
util.inherits(Customer, Entity);
const start = async function() {
return new Promise(async (resolve, reject) => {
const uri = "mongodb://localhost:27017/";
console.log("connecting");
mongo.once("connected", async () => {
console.log(`connected`);
const repo = new Repository(Customer);
const getAll = promisify(repo.getAll);
try {
console.log(`getting customers`);
const customers = await getAll();
console.log("customers", customers);
return resolve();
} catch (err) {
return reject(err);
}
});
mongo.connect(uri);
});
};
start();
Running this code results in TypeError: Cannot read property 'distinct' of undefined after the await getAll() call.
The same happens when using bluebirds promisify function as suggested in https://github.com/mateodelnorte/sourced-repo-mongo/issues/13#issuecomment-239321801
I think it's a timing issue, regarding the repo's ready event. I don't see anything that should be async, between the new call and it's usage, but you're likely getting an error on this line and self.events.distinct property.
self.events is set here. Again, it's a little funny, as I don't see any async ops going on between that property being set and the usage.
Does changing your usage to something like the following help?
mongo.once("connected", async () => {
console.log(`connected`);
const repo = new Repository(Customer);
repo.on('ready', () => {
const getAll = promisify(repo.getAll);
try {
console.log(`getting customers`);
const customers = await getAll();
console.log("customers", customers);
return resolve();
} catch (err) {
return reject(err);
}
});
});
Dunno if it's somehow manifesting itself with the usage, but I usually just put my repo definitions in their own file.
const Trader = require('./models/trader');
const Repo = require('sourced-repo-mongo').Repository;
const util = require('util');
function TraderRepository () {
Repo.call(this, Trader);
}
util.inherits(TraderRepository, Repo);
module.exports = new TraderRepository();
This ends up being helpful if I start using the decorator pattern to add over overlay behavior on the new repo type:
const Trader = require('./models/trader');
const Repo = require('sourced-repo-mongo').Repository;
const Queued = require('sourced-queued-repo');
const util = require('util');
function TraderRepository () {
Repo.call(this, Trader);
}
util.inherits(TraderRepository, Repo);
module.exports = Queued(new TraderRepository());
@mateodelnorte Thanks for your reply. In fact, my initial code looked quite similar to your second suggestion. My sample above was just simplified for repro.
Are you still having the issue? Otherwise, did you try the suggestion here.
Yes, I'm still having the issue (if I'm not using a workaround wrapping the sourced-repo-mongo calls in Promises which are called using async/await then).
If I'm using your code as suggested:
mongo.once("connected", async () => {
console.log(`connected`);
const repo = new Repository(Customer);
repo.on('ready', () => {
console.log('ready')
const getAll = promisify(repo.getAll);
try {
console.log(`getting customers`);
const customers = await getAll();
console.log("customers", customers);
return resolve();
} catch (err) {
return reject(err);
}
});
});
I'm getting this error:
const customers = await getAll();
^^^^^^
SyntaxError: Unexpected identifier
at createScript (vm.js:74:10)
at Object.runInThisContext (vm.js:116:10)
at Module._compile (module.js:533:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:575:3
If I add the async keyword like shown here:
mongo.once("connected", async () => {
console.log(`connected`);
const repo = new Repository(Customer);
repo.on('ready', async () => { // async added here
console.log('ready')
const getAll = promisify(repo.getAll);
try {
console.log(`getting customers`);
const customers = await getAll();
console.log("customers", customers);
return resolve();
} catch (err) {
return reject(err);
}
});
});
I don't get any errors, but it looks like the ready event of repo is never executed:
⋙ node index.js
connecting
connected
@AlexZeitler Did you ever find a workaround for this?
I too have not been able to connect to the ready event of any Repository instance.
@pcopley No, didn't solve it.