theara
August 29, 2017, 3:15pm
21
And then I tried with Meteor Method
, but still don’t work (base on Meteor 1.5)
import Counters from './counters';
Meteor.methods({
getNextSequence: function (name) {
const ret = Counters.rawCollection().findAndModify(
{
query: {_id: name},
update: {$inc: {seq: 1}},
new: true,
upsert: true
}
);
console.log(ret.seq);
return ret.seq;
}
});
Check my code - I used async
and await
.
theara
August 30, 2017, 12:10am
23
I tried with async and await
, but still don’t work
Meteor.methods({
getNextSequence: async function (name) {
const ret = await Counters.rawCollection().findAndModify(
{
query: {_id: name},
update: {$inc: {seq: 1}},
new: true,
upsert: true
}
);
console.log(ret.seq);
return ret.seq;
}
});
@orloff I had this same issue with FindAndModify is not a function. I got it working after installing meteor-find-and-modify
meteor add fongandrew:find-and-modify
. Though this package isn’t actively maintained at the moment, it worked for me. It adds findAndModify support to Meteor’s MongoDB Collections. It should work on both the server and client.
theara
August 30, 2017, 6:49am
25
@martineboh , thanks for your share.
but this package isn’t actively maintained
Yes, but works! I have had no issues using it since Meteor 4+.
Using rawCollection()
gives you access to these methods , including findAndModify
.
However, it turns out that findAndModify
has been deprecated and a bunch of new methods has been added. So, I’ve rewritten @theara ’s method to use findOneAndUpdate()
:
Meteor.methods({
async getNextSequence(name) {
const ret = await Counters.rawCollection().findOneAndUpdate(
{ _id: name },
{ $inc: { seq: 1 } },
{ upsert: true, returnOriginal: false }
);
return ret.value.seq;
}
});
Hope that helps
1 Like
@robfallows Thanks for the updates! Found its usage in the mongo docs
1 Like
It seems findAndModify
isn’t deprecated yet according to here and here in the docs.
I really like the way you use Async/Await with Meteor Methods. Can you please rewrite the example with try/catch to show error handling…thanks
I was going by the API docs - and it’s the API which Meteor uses - so I’m playing safe .
Meteor.methods({
async getNextSequence(name) {
try {
const ret = await Counters.rawCollection().findOneAndUpdate(
{ _id: name },
{ $inc: { seq: 1 } },
{ upsert: true, returnOriginal: false }
);
return ret.value.seq;
} catch (error) {
throw new Meteor.Error('ENEXTSEQ', 'Failed to get next sequence number');
}
}
});
2 Likes
theara
August 30, 2017, 12:45pm
31
@robfallows , thanks for your helping.
But I would like to call this in Collection Hook
Units.before.insert(function (userId, doc) {
console.log(getNextSequence.run('unitId'));
........
});
dont’ work, get Promise { <pending> }
Have you tried
Units.before.insert(async function (userId, doc) {
console.log(getNextSequence.run('unitId'));
........
});
theara
August 30, 2017, 1:00pm
33
still get Promise { <pending> }
Sorry, forgot that getNextSequence
was an async
function (btw - not sure where that .run
is coming from…). Maybe something like this?
async function getNextSequence(name) {
const ret = await Counters.rawCollection().findOneAndUpdate(
{ _id: name },
{ $inc: { seq: 1 } },
{ upsert: true, returnOriginal: false }
);
return ret.value.seq;
}
//...
Units.before.insert(async function (userId, doc) {
const nextSeq = await getNextSequence('unitId');
console.log(nextSeq);
doc._id = nextSeq;
........
});
theara
August 30, 2017, 1:22pm
35
It work fine.
So it means that we must create getNextSequence
as general function
, if we want to use it in server (don’t Meteor Method)
You can use it in an async
method if you want.
theara
August 30, 2017, 1:42pm
38
Wow, have problem when I attache nextSeq
with doc._id
Units.before.insert(async function (userId, doc) {
const nextSeq = await getNextSequence.run({name: 'unitId'});
doc._id = nextSeq;
console.log('before', doc);
});
Units.after.insert(async function (userId, doc) {
console.log('after', doc);
});
------------
I20170830-10:40:25.188(7)? after { name: 'Hi', category: 'Count', _id: 'PhvXJn7FBn3pesPxk' }
I20170830-10:40:25.194(7)? before { name: 'Hi', category: 'Count', _id: 5 }
Ah, yes. You can’t use numbers as MongoDB _id
s - you’ll either need to force them to strings, or append them to a string:
doc._id = nextSeq.toString(); // or ...
doc._id = `${nextSeq}`; // or ...
doc._id = `abc${nextSeq}`; // etc...
theara
August 30, 2017, 2:02pm
40
It mean that inserts random id
before nextSeq id
return (console
on before hook
run after after hook
).
I20170830-10:59:27.693(7)? after { name: 'Hi', category: 'Count', _id: 'roMLDXgaN6eg2ww48' }
I20170830-10:59:27.699(7)? before { name: 'Hi', category: 'Count', _id: '6' }