Meteor: How can I retrieve the inserted _id inside a method? - mongodb

I have a meteor method to insert a document. The id for that document serves as a url extension. After the document is created, I also send an email via the same method. In the email, I want to include a link to the url extension. How can I do that?
//create a video
Meteor.methods({
createVideo: function(doc) {
Videos.insert({title: doc.title, userId: this.userId, date: new Date()});
var emailData = {
message: "Click the link below to go to your video.",
buttontext: "View My Video",
buttonlink: "http://sample.com/vids/" + ???????
},
body = EmailGenerator.generateHtml("actionEmailTemplate", emailData);
Meteor.call("sendMailgunEmail",
"account#sample.com",
"sample",
[Meteor.user().emails[0].address],
"Your video is live!",
body
);
}
});

From Meteor Docs:
collection.insert(doc, [callback])
Insert a document in the collection. Returns its unique _id.
So you can grab the _id from your insert by storing it in a local variable
var videoId = Videos.insert({title: doc.title, userId: this.userId, date: new Date()});

Check out the Meteor documentation for collection.insert:
Insert a document in the collection. Returns its unique _id.
Just assign the return value of the insert to a variable you can reference later:
//create a video
Meteor.methods({
createVideo: function(doc) {
var videoId = Videos.insert({title: doc.title, userId: this.userId, date: new Date()});
var emailData = {
message: "Click the link below to go to your video.",
buttontext: "View My Video",
buttonlink: "http://sample.com/vids/" + videoId
},
body = EmailGenerator.generateHtml("actionEmailTemplate", emailData);
Meteor.call("sendMailgunEmail",
"account#sample.com",
"sample",
[Meteor.user().emails[0].address],
"Your video is live!",
body
);
}
});

Related

MongoDB update a specific item of sub document (array) based on condition?

I have a PostSchema which has a property array called votedBy:[],this is of type votedBySchema.Like below:
var votedBySchema = new Schema({
voteType:{
type:Boolean,default:false
},
voter:{
type:Schema.Types.ObjectId
}
});
const PostSchema = new Schema({
_authorId:{
type:Schema.Types.ObjectId,
required:true
},
title:{
type:String,
required:true
},
body:{
type:String,
},
date:{
type:Date
},
hidden:{
type:Boolean,
default:false
},
popularity:{
type:Boolean
},
votedBy:[{
type:votedBySchema,
}]
});
Now I fire a patch request from postman with to url /post/:postId.Here I run a middleware which checks if user requesting has a valid token.And put userObject and token on req object.
Next I want that if user is author of the post then he can change everything about the post but if he is not the author then he can only change popularity i.e upVote or downVote.
My logic was that every voting person must be registered in votedBy array.
like:
votedBy:[
{voteType:true,voter:'abcd#gmail.com'}, //upvote
{voteType:false,voter:'pqrs#gmail.com'}//downvote
]
As Email is unique one must only be able to upVote or downVote so unique entry on basis of email in votedBy.
my route logic code:
app.patch('/post/:postId',authenticate,(req,res)=>{
console.log("[server.js]=>request ${req.method} to ${req.url}")
let body = _.pick(req.body,["title","body","popularity","hidden"])
let user = req.user;
let userId = user._id;
let postId = req.params.postId;
Post.findById(postId).then((post)=>{
let oldPost = post;//No use in code
console.log(`Found post ${post}`);
let postAuthorId = post._authorId.toString();
if(postAuthorId == userId){
post.title = body.title || post.title;//new,old
post.body = body.body || post.body;
post.hidden = body.hidden ||post.hidden;
post.update(post,{new:true}).then((postUpdated)=>{
console.log("Post Updated");
res.send(postUpdated);
});
}
else{
let voter = user.email;
console.log("\n voter is \n",voter)
let voteType = body.popularity;
//below code needs to be changed
/* post.update(
{
$set:{
'votedBy.$.voteType':voteType,
'votedBy.$.voter':voter
}
},
{
new:true
}
).then((iDontKnow)=>{
console.log('I dont know',iDontKnow);
res.send(post);
})*///Update or push the votedBy array for voter
}
});
});
Note I want to give a voting feature same as fb/youtube.
Also suggest if there is any other way around.
Idea of doing this is fine but if I would have implemented this will have kept userId for mapping rather than user email.
Eventually you will have that post from front end so you can send value from front end, but that will not be a that good a method.
post.findOneAndUpdate( { userId : 'id of user from session' }, { "votedBy.$. voteType" : "true/false"}, { upsert : true }, callback );
So you need to perform find operation first to get value of vote type for particular user and then update it
Route code will be something like
dbOperation.getPostData(request.body.postId, userId , (err,result)=>{
if(err){ //log the error}
else if(result!=undefined){
dbOperation.updatePost(request.body, (err,result)=>{
if(err){ //log the error}
else{
response.json({message:'update',code:200,success:true});
}
});
else{
response.json({message:'post not found',code:404,success:false});
}
});

Meteor - MongoDB _id

I want to assign the MongoDB _id primary key to a variable but cannot do it. When I look at the record in the collection, the postID shows up as undefined - code listed below. How can I fix this? I want the postID to match the _id. Thanks in advance!
Template.postNewJob.events({
'submit form': function(event) {
event.preventDefault();
var position = $('[name=position]').val();
var jobDescription = $('[name=jobDescription]').val();
var createdAt = new Date();
var createdBy = Meteor.userId();
var postID = this._id;
postedJobs.insert({
position: position,
jobDescription: jobDescription,
createdAt: createdAt,
createdBy: createdBy,
postID: postID
});
Router.go('dashboard');
}
});
if postId will always be your document id then there may be another way of doing this. You may use collection hooks . Refer here
https://github.com/matb33/meteor-collection-hooks
and use a function as below in your server side file
postedJobs.after.insert(function (userId, doc) {
doc.postId=this._id
});
I was able to find some helpful info from another posting and was able to solve this issue. The reference page is objectId from url to match with one in the mongo using meteorjs
Thanks!

How to show data from mongoDB with ObjectID

i have an "back end" application which write in MongoDb (in database i have _id: with ObjectId("13f6ea...002")) i use meteor app to show information. Everything was good i displays list of information with {{#each}}. But when i wanted show one element with '_Id' nothing works.
I read this issue and adapt my code to get right root, But i can't display anything on the page. I tried to write Template helpers but it didn't helped
Db record:
{
_id: ObjectId("13f6ea...002"),
url: "foo",
title: "bar",
published: "2014-08-22 03:26:21 UTC",
image: "foo.jpg",
summary: "foo ",
categories: [
"F",
"B"
],
...
}
Route:
this.route('news', {
path: '/news/:_id',
template: 'news',
waitOn: function () {
var id = this._id;
Meteor.subscribe('news', id);
},
data: function() {
var id = this.params._id;
return News.findOne({ _id: Meteor.Collection.ObjectID(this.params._id)});
},
action : function () {this.render();},
});
Publish
Meteor.publish('news', function(id) {
return News.find({_id: id});
});
Template which redirect to unique post
<h4>{{title}}</h4>
And template is just {{news}}
How can i fix this?
UPDATE
My solutions to fix that:
router.js
waitOn: function () {
var id = this._id;
Meteor.subscribe('News', id);
},
data: function() {
return News.findOne(new Meteor.Collection.ObjectID(this.params._id));
},
and in template
<a href="news/{{_id._str}}">
Navigate to the appropriate url in your browser (i.e. localhost:3000/news/[_id]), open the console and enter:
Router.current().data()
That will show you the data context of the current route. Either it returns nothing, in which case there is a fundamental problem with your News.findOne query as it's returning nothing, or (more likely) it returns the required document.
In the latter case, as far as I can see there is no news property within that document, which is why it isn't rendering anything. If you change {{news}} to {{url}} or {{summary}} I would imagine it would render the requested property.
If by {{news}} you're trying to render the entire document, then (aside from the fact that it will render as something like [Object]) you need to make news a property of the object returned by your data function:
return {
news: News.findOne({ _id: Meteor.Collection.ObjectID(this.params._id)});
};
Getting Document with _id :
In the .js file under events, Say on click event and Collection EventList :-
'Submit form' : function () {
var id = this._id;
return EventList.find({_id : id}).fetch();
}
This would return the object for the id. In my Case, I am displaying a field for all documents in Collection. User selects a record and clicks Submit, which fetches all Document fields and displays to the User

How to get the inserted document's ID in MongoDB

I'm writing a script for the mongo shell to populate some data for test.
I have two collections: club, and team, and in the team's document, it has a objectId reference to the club.
What I did is as following:
db.club.drop();
var club_1_id;
db.club.insert({name:'Club 1',
venue:'Somewhere'},
function(err, doc){
club_1_id=doc._id;
});
db.team.drop();
var team_1_id;
db.team.insert({name:'Team 1', club:{id: club_1_id, name: 'Club 1'}},
function(err, doc){
team_1_id=doc._id;
});
I'm actually not so surprised to see that in the team document, the club's ID is inserted to be null, cause the call-back function may not be called in a timely fashion.
So in this case how can I set the id right?
You could try something like:
db.club.drop();
var club_1_id = new ObjectId();
db.club.insert({_id:club_1_id, name:'Club 1',venue:'Somewhere'});
db.team.drop();
var team_1_id = new ObjectId();
db.team.insert({_id:team_1_id, name:'Team 1', club:{id: club_1_id, name: 'Club 1'}});
var club_doc = {
_id: ObjectId()
name:'Club 1',
venue:'Somewhere'
}
var id = club_doc._id;
db.club.insert(club_doc);
var team_doc = {
_id: ObjectId(),
name:'Team 1',
club:{
id: id,
name: 'Club 1'
}
}
var teamID = team_doc._id;
db.team.insert(team_doc);

How to get last inserted id using the JS api?

Using the javascript api for MongoDB, how do you get the ID of the last inserted object? i.e.
obj = {a: 1, b: 2};
db.foo.insert(obj);
How do I get the ID for obj?
The people on #mongodb were helpful. The JS API doesn't currently support this, but you can use your own id. To generate a "normal" id, do _id: new ObjectId(). So the example in my question would be:
id = new ObjectId();
obj = {a: 1, b: 2, _id: id};
db.foo.insert(obj);
If you run
db.collection("venues").insert( {name: "test3", FSid: "test3"}, function( err, ret) {
console.log( ret )
})
it returns
{ result: { ok: 1, n: 1 },
ops: [ { name: 'test3', FSid: 'test3', _id: 57cb0a1162cecfe636df6fc1 } ],
insertedCount: 1,
insertedIds: [ 57cb0a1162cecfe636df6fc1 ] }
So you can get your ids along with all inserted objects through:
ret.ops[0]._id
or straight
ret.insertedIds[0]
Now,the mongo native js api supports this. You can get the last id like this:
collection.insert(line, {w : 1}, function(err, inserted) {
inserted[0]._id
}
insert sets the _id property on the inserted object, but it looks like you have to wait for the object to return. The best documentation I've found for this is (unfortunately) in the source code:
https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js
If you insert the data like this:
var temptodo = new User({
title: data.todo.text,
email: socket.handshake.email,
created_at: Date.now(),
completed: false,
sid: socket.handshake.sid
});
temptodo.save( function(error, User){
console.log("this is the id for the new todo. "+User._id);
console.log('Todo saved in database with sid: '+socket.handshake.sid);
});
Then you can grab the _id like this: console.log("this is the id for the new todo. "+User._id);