I'm using Mongoose for MongoDB operations in my project. I'm trying to:
find every document matching query
create a new object (let's call it objects)
for every document found create a new object inside objects
save fields from found document to created object
And this works just fine. But I also want to:
for every object saved inside my objects find one document matching query in another collection
if document is found, save fields from it to previously created object objects (as new keys)
My code for the second part looks like this:
for(var i in objects) {
if(objects.hasOwnProperty(i)) {
Model.findOne({name: objects[i].name, id: objects[i].id}, function(e, document) {
if(e) console.error(e);
if(document) {
console.log("Found matchind document"); //This is showed for each object, as expected.
objects[i].newField = document.someData;
objects[i].evenNewerField = document.someMoreData;
}
});
}
}
console.log(objects); //This shows old data from previous operations, no new data from the for loop
Your problem is not your mongoose usage, you should take a deep look to Javascript scope and asynchronous. In your code when console.log is called, objects is not yet updated.
Related
I have a form on a users page that calls a method, 'newDiscussion' to create a new discussion object between the logged in user (hereafter: user1) and the user whose page they're on (hereafter: user2). It also created a message object with a discussionId matching the newly created discussion object.
In the discussion object, I store user1._id and user2._id.
I want check whether an existing discussion object contains these two users Id's. If false, proceed as above, else just insert the message and make the discussionId match the existing discussion object Id.
Assuming you already have the discussion published to your client, you can use collection.findOne method in your client code like this
var dicussion = Discussions.findOne({'user1._id': Meteor.userId(), 'user2._id': 'another user id'});
if (discussion) {
// do some updates, if necessary
}
else {
// else create a new discussion
}
In my cloud code I want to retrieve the first object in the "Messages" class. Then i want to grab some information from that object, send it to another class, and finally delete that object from the "Messages" class i originally pulled it from.
My question is do i need to query the entire "Messages" class just to get the first object in it? I don't want to slow down my app due to inefficient code.
Parse.Cloud.afterSave("sendMessage", function(Parse.Message, response) {
var body = null;
var senderName = null;
var senderId = null;
var randUsers = [];
var query = new.Parse.Query(Parse.Message);
query.find({
success: function(results){
body.push(results[1].get("messageBody"));
senderName.push(results[1].get("senderName"));
senderId.push(results[1].get("senderId"));
response.success(getUsers);
},
error: funtion(error){
response.error("Error");
}
});
});
to avoid confusion: "getUsers" is an arbitrary function call.
To retrieve entry from class, you need the query the table. However, your problem is getting the first record which does not require getting the all record. From your code I can see that you get the first record of result array (result[1] ). You can apply the solution; getting the first record of the class that you want to query. You can do it via two ways; either you can set the limit 1 to your query or you can use the first() method. The Parse.Query JS API link is below;
https://parse.com/docs/js/symbols/Parse.Query.html
Check the limit and first methods.
Hope this helps.
Regards.
On my page I initially declare variable var as which creates an object through plugin using createAll... I'm referring to this plugin: http://kolber.github.io/audiojs/docs/
In order for plugin to work this object needs to be created. So after that I load some contact through ajax and plugin needs to be applied to this new content, so again I create this var as to create object, however now there are two similar objects on a page which conflict. I would like to know it there is a way where I can make var as that gets created after ajax call equal to existing object on a page?
I tried looking at what's inside var as by doing alert(as); This returns [Object object]
EDIT
This is what gets printed out with console log (This is original, first object)
Object
duration: 1
element: HTMLAudioElement
loadStartedCalled: false
loadedPercent: 0
mp3: null
playing: false
settings: Object
source: HTMLAudioElement
wrapper: HTMLDivElement
__proto__: Object
This is how objects are created, but I believe you need to know the plugin well to understand this
// Initialize audio js
audiojs.events.ready(function() {
var as = audiojs.createAll({
});
});
I've tested a working solution. Please note, the code is just to show it works - see my explanation below for specifics.
var as;
audiojs.events.ready(function () {
as = audiojs.createAll();
});
$(document).ready(function () {
setTimeout(function () {
var mp3 = "http://s3.amazonaws.com/audiojs/02-juicy-r.mp3"; // audio.js example
// creating new audio element, yours is probably added via ajax
// [0] used to get DOM element instead of jQuery object.
var audio = $('<audio/>', {id: 'test'}).appendTo('body').attr('src', mp3)[0];
var testAS = audiojs.create(audio); // initialise new audio.js player
as.push(testAS); // add "testAS" object to "as" array of objects
console.log(as); // log "as" - now holds the original objects + "testAS"
}, 5000); // timeout used for testing, above code can be in ajax success function instead
});
The mp3 and audio variables are just used as a demonstration as I don't know your ajax function's structure.
Audio.js has a .create() function which takes a single element as it's argument and returns an object. The original as variable is an array containing all the audio objects so you can just push the new object onto the end.
By defining as outside a function you make it global meaning that everything can access it and any new audio.js objects can be appended.
I've got a "LocalStore" object for storing data locally. It's based around a Lawnchair object.
var LocalStore = function(name) {
var that = this;
that.name = name;
that.lawnchair = Lawnchair({ name: that.name }, function(store) {
this.before('save', function(record){
console.log("saving " + that.name);
console.log(record);
});
this.after('save', function(record){
console.log("saved " + that.name);
console.log(record);
that.getData(function(records){
console.log("now it's this");
console.log(records);
});
});
});
that.getData = function(callback) {
that.lawnchair.get(that.name, callback);
};
};
LocalStore is then extended with _.extend(from the Underscore.js library) with this method:
save: function(collection, callback) {
this.lawnchair.save({ key:this.name, value: collection }, function(record) {
callback(record);
});
}
This code is used to update a Backbone.js Collection object to Lawnchair. The first time "save" runs for my Users Collection it saves correctly and shows that the object is a simple key/value pair where value is an Array.
Later in my code when a User selects a Default Project, I modify the Users Collection and call "save" again with an updated "defaultProjectId" on the User. The code runs error free, but the after('save') code for Lawnchair runs and shows me that:
- The record object returned is a key/value pair where value is a full Backbone.js Collection with the defaultProjectId property set correctly.
- The getData method that grabs the latest from the Database still shows as a key/value pair with value a simple Array and defaultProjectId is set incorrectly.
I'm at a loss as what to do. It should just be simply calling "lawnchair.save" updates the record, but it just doesn't do it.
Could you try this jsfiddle?
http://jsfiddle.net/QUgtg/1/
I have recreated your code. Instead of a backbone collection, I am passing in an array of objects. This seems to work. You can see the logging output in Firebug.
I have used my own extend code to add the save(). Though honestly, I don't see why you would want to do it that way, instead of just adding a property to the prototype. Your code may differ in that aspect.
If what I have posted works on your end, could you modify that code to show what are you doing differently? If possible, recreate the issue on jsfiddle...
I have two objects: command and topic.
topic has a method actions that is called from command.
When topic.actions() is called, there are no errors.
When I use the object property command.taxonomy whose value is the string 'topic' to call topic.actions(), an exception is thrown: "Object topic has no method actions".
Why would the console report topic has no method actions when it is right there?
command = {
/*this is set when an html element is clicked by another function:
for this example, it equals the string 'topic'*/
taxonomy : '',
//this is called when the same html element is clicked as above
taxonomy_actions: function(){
this.taxonomy.actions();
}
}
topic = {
actions:function(){
//returns an array of valid commands for topic
this.commands.push('shortcuts');
this.commands.push('action_list');
this.commands['shortcuts'] = new Array();
this.commands['action_list'] = new Array();
for(x in this.aliases){
this.commands.action_list.push(this.aliases[x]);
this.commands.shortcuts.push(x);
}
return this.commands;
}
}
It's actually mostly there in your question:
whose value is the string 'topic' to call ...
What you want is to access the 'topic' property of the Object that contains the topic{} object.
Therefore you want:
taxonomy_actions: function(){
containing_object[this.taxonomy].actions();
}
The containing object (if you didn't attach topic to something) would be window in browser environments or global in NodeJS.