Document disappears after being inserted into db in Meteor - mongodb

trying to add to my very simple collection using
Template.home.events({
'click #send-button': function(e, t) {
e.preventDefault();
msg = {
from: Meteor.user()._id,
to: Meteor.user().penpal,
sent: new Date(),
message: $('#message').val()
};
messages.insert(msg);
console.log(messages.find().fetch());
}
})
in collections.js I have
messages = new Mongo.Collection('messages');
messages.allow({
'insert': function (userId,doc) {
return true;
}
});
message gets inserted but the console shows that it is being overwritten every time, eg it adds my new message but does not keep all old messages as well. when I try to render messages using
Template.home.helpers({
'messages': function(){
return messages.find().fetch();
}
})
and then
{{#each messages}}...{{/each}}
in html I get the messages appearing for the blink of an eye and then disapearing again.
please help! I am desperate!

Based on the Q&A, it appears you simply need to publish the collection and subscribe to it:
server:
Meteor.publish('myMessages',function(){
const me = this.userId;
if ( me ){
return messages.find({ $or: [{ from: me },{ to: me }]});
}
this.ready();
});
(in the code above the collection is being filtered to messages that are pertinent to the current user, you can define your own filters as required).
client:
Meteor.subscribe('myMessages');

Related

Unable to get specific data from javascript object gotten from mongo database

I'm trying to get specific info from a javascript object from a mongo database. My code is
tags.find({tagName: tagArgs[1]}, function (err, tag) {
if (err) {
} else {
msg.channel.send(tag.tagContent)
}
})
What I want happened is for the content of the tag to be sent, however, instead it sends nothing. If I instead did
msg.channel.send(tag)
I would get an object
{
_id: 6071ce10c7b87d58acfeac7e,
tagName: 'Test',
tagContent: 'hello world',
__v: 0
}
but trying to tap into tagContent returns nothing, what am I doing wrong?

Unable to get the id of newly created record sails js

I am creating a new record like this:
Resource.create({
title: req.body.title,
address: {...req.body.address},
email: req.body.email,
}, (err, record) =>{
if(err){
res.send({'status': err});
}else{
res.send(
{
'status': 'it worked',
'data': req.body
}
);
sails.log(record.title)
}
});
The request process perfectly and the new record is added to the database(I can see it too). But I cant get the id right when its created for some weird reason.
I've been following a tutorial and record is supposed to not be undefined, I am using MongoDB with SailsJS
You have to chain a "fetch" after creating the record, for example:
let resource = Resource.create({...}).fetch();
This will fetch the record you just created with its associated id.

Mongo `pre` hook not firing as expected on `save()` operation

I am using pre and post hooks in my MongoDB/Node backend in order to compare a pre-save and post-save version of a document so I can generate notes via model triggers based on what's changed. In one of my models/collections this is working, but in another, it's not working as expected, and I'm not sure why.
In the problem case, some research has determined that even though I am calling a pre hook trigger on an operation that uses a save(), when I console out the doc state passed in that pre hook, it's already had the change applied. In other words, the hook is not firing before the save() operation, but after, from what I can tell.
Here is my relevant model code:
let Schema = mongoose
.Schema(CustomerSchema, {
timestamps: true
})
.pre("save", function(next) {
const doc = this;
console.log("doc in .pre: ", doc); // this should be the pre-save version of the doc, but it is the post-save version
console.log("doc.history.length in model doc: ", doc.history.length);
trigger.preSave(doc);
next();
})
.post("save", function(doc) {
trigger.postSave(doc);
})
.post("update", function(doc) {
trigger.postSave(doc);
});
module.exports = mongoose.model("Customer", Schema);
The relevant part of the save() operation that I'm doing looks like this (all I'm doing is pushing a new element to an array on the doc called "history"):
exports.updateHistory = async function(req, res) {
let request = new CentralReqController(
req,
res,
{
// Allowed Parameters
id: {
type: String
},
stageId: {
type: String
},
startedBy: {
type: String
}
},
[
// Required Parameters
"id",
"stageId",
"startedBy"
]
);
let newHistoryObj = {
stageId: request.parameters.stageId,
startDate: new Date(),
startedBy: request.parameters.startedBy,
completed: false
};
let customerToUpdate = await Customer.findOne({
_id: request.parameters.id
}).exec();
let historyArray = await customerToUpdate.history;
console.log("historyArray.length before push in update func: ", historyArray.length);
historyArray.push(newHistoryObj);
await customerToUpdate.save((err, doc) => {
if (doc) console.log("history update saved...");
if (err) return request.sendError("Customer history update failed.", err);
});
};
So, my question is, if a pre hook on a save() operation is supposed to fire BEFORE the save() happens, why does the document I look at via my console.log show a document that's already had the save() operation done on it?
You are a bit mistaken on what the pre/post 'save' hooks are doing. In pre/post hook terms, save is the actual save operation to the database. That being said, the this you have in the pre('save') hook, is the object you called .save() on, not the updated object from the database. For example:
let myCustomer = req.body.customer; // some customer object
// Update the customer object
myCustomer.name = 'Updated Name';
// Save the customer
myCustomer.save();
We just updated the customers name. When the .save() is called, it triggers the hooks, like you stated above. Only the difference is, the this in the pre('save') hook is the same object as myCustomer, not the updated object from the database. On the contrary, the doc object in the `post('save') hook IS the updated object from the database.
Schema.pre('save', function(next) {
console.log(this); // Modified object (myCustomer), not from DB
)};
Schema.post('save', function(doc) {
console.log(doc); // Modified object DIRECTLY from DB
});

Overwrite object in mongodb

This should be simple but it is surprisingly difficult and extremely frustrating. I am trying to overwrite an 'Object' field in mongodb with a new Object that the user creates in my client webpage. I have validated that all other fields I am passing to the update operation are in fact being updated, with the exception of the javascript object. Instead of it updating with the object I am passing (While I validated is being populated with the object I am passing through), it just updates it back to {} instead of whats being passed:
{ nodes:[ { w: 120, h: 80,type: 'InHive',left: 184,top: 90,text: 'item',query: 'hey',name: 'sample',id: '7686132d-6fcf-4a3b-baa2-b1c628e0b2d6' } ], edges: [], ports: [],groups: [] }
When I attempt to update the data field outside of the meteor method, directly from the mongo console interface, it overwrites that field successfully with the javascript object. What am I doing wrong here, because I cant for the life of me figure this one out?
Server Method
'updateOneWorkflow': function(id, field, object) {
this.unblock;
if (Meteor.userId()) {
var _username = Meteor.user().username;
MYCOLLECTION.update({
_id: id
}, {
$set: {
[field]: object, //this just gets reset back to {} whenever this update method is called
"metadata.last_modified_dt": new Date(), //this gets updated
"metadata.modified_by": Meteor.userId(), //this gets updated
'metadata.modified_by_username': _username //This gets updated
}
});
} else {
throw new Meteor.Error(403, "You are not authorized to perform this function");
}
}
Client Call:
var _jsonformat = toolkit.exportData();
var currentid = Session.get('rulesRowClicked')._id;
console.log(_jsonformat);
Meteor.call('updateOneWorkflow' , currentid, 'data', _jsonformat, function(err, res){
if(err){
toastr.error('Failed to save result ' + err);
}
else{
toastr.success('Saved workflow');
}
});
I believe your problem is stemming from this line: [field]: object. I don't believe that's a proper method of dynamically accessing an object's field. Instead, try to dynamically update the field as so:
'updateOneWorkflow': function(id, field, object) {
this.unblock;
if (Meteor.userId()) {
var _username = Meteor.user().username;
var newObj = {
"metadata": {
"last_modified_dt": new Date(),
"modified_by": Meteor.userId(),
"modified_by_username": _username
}
};
newObj[field] = object;
MYCOLLECTION.update({
_id: id
}, {
$set: newObj
});
} else {
throw new Meteor.Error(403, "You are not authorized to perform this function");
}
}
The issue was crazier than I expected. If you are using Meteorjs and you are using the Aldeed Schema 2 collection framework, it seems to completely ignore updates/inserts of json objects even if you set the field type to Object, unless you set up the exact same schema as the object (including nested array objects) and attach it to your collection. Dumbest thing Ive ever seen, no idea why nothing warns you of this. I removed the schema attachment and it worked.

Mongoose findByIdAndUpdate not working

I have a fairly straight forward method below to update a document based on its ObjectId. It does not return an error but it fails to make the required updates to the document. I think it is failing because, according to my research, findByIdAndUpdate() takes only plain Javascript whereas job._id is an ObjectId from the document that I want to update. Can someone tell me how to make this work correctly?
function handleEncoderResponse(xmlResponse, job) {
var r = et.parse(xmlResponse);
var mediaID = r.findtext('./MediaID');
var message = r.findtext('./message');
EncodingJob = mongoose.model('EncodingJob');
EncodingJob.findByIdAndUpdate( job._id, {
"MediaID": mediaID,
"Status": message
}, function(err, result) {
if (err) console.log(err);
console.log(result);
});
}
Edit: Per this question Mongoose update document Fail with findByIdAndUpdate
I also tried the following code to no avail.
job.MediaID = mediaID;
job.Status = message;
job.save(function(err, res) {
if(err) console.log(err);
});
This approach yields the issue. It does not update the document and it does not return an error.
As it turns out, my mistake was forgetting to define MediaID and Status in the Schema as follows:
var encodingJobSchema = new mongoose.Schema({
...
MediaID: String,
Status: String
});