meteor dbmongo find does not return all the elemnts - meteor

I'm using meteor and javascript fullcalendar .
I'm trying to get the data from a dbmongo cursor.
But it's seem really randomly when I get the elements and when I don't
Here is my code :
events : function (start, end , timezone, callback) {
var events = [];
var eventsData = Events.find();
eventsData.forEach(function(event) {
events.push(event);
});
callback (events);
}
This sits inside the isClient, in the jquery section.
Sometimes I get all the elements form the database and sometimes I don't.
Anybody have an idea on how to always get them?
Thanks

Related

Get Dropdown Value in Meteor Js?

I did one sample Searchapp using meteor add sebdah:autocompletion package.When ever given inputs it shows drop down list.In this list how to get selected value as shown below code:
Js Code :
Friends = new Meteor.Collection('friends');
if (Meteor.isClient) {
/**
* Template - search
*/
Template.search.rendered = function () {
AutoCompletion.enableLogging = true;
var res = AutoCompletion.init("input#searchBox");
console.log("res :"+res);
}
Template.search.events = {
'keyup input#searchBox': function (e,t) {
AutoCompletion.autocomplete({
element: 'input#searchBox', // DOM identifier for the element
collection: Friends, // MeteorJS collection object
field: 'name', // Document field name to search for
limit: 0, // Max number of elements to show
sort: {name: 1}
});
}
}
}
I didn't get any idea about this.So please suggest me how to get selected drop down list values?
AutoCompletion package doesn't give any good API to read value on select. Instead you need to manually read the value of input#searchBox.
Please take a look at source code.
I would recommend to implement searching in your meteor app using Arunoda's approach : https://meteorhacks.com/implementing-an-instant-search-solution-with-meteor.html

How to change the value of a variable on click in meteor

In my meteor app I need to load an array of items corresponding to the item clicked.As I'm new to meteor, I'm held up here.Here is my code.
Template.templatename.events({
'click .showdiv' : function()
{
Template.templatename.vname = function () {
return Db.find();
}
}
Can I set the variable vname dynamically by this code ? This is not working for me.
I think you're misunderstanding the notion of reactivity. A reactive data source will cause any functions which depend on it (including helpers) to rerun when its value is changed, which seems to be the behavior you're looking for here. Instead, you're rewriting the helper function itself every time an item is clicked, which kind of defeats the object of Meteor's reactive data model. Session variables could help:
Template.templatename.events({
'click .showdiv' : function() {
Session.set('vname', Db.find());
}
});
Template.templatename.vname = function () {
return Session.get('vname');
}
If you use an {{#each vname}} block in the templatename template, it will automatically update with the results of the Db.find() query when a .showdiv is clicked. If all you want to do is show the result of that query regardless of whether a click has been registered it would be as simple as:
Template.templatename.vname = function () {
return Db.find();
}
Note that it's still not clear exactly what data you're trying to populate here since the query will return a cursor (which is fine, but you need to loop through it using {{#each ...}} - use findOne if you only want one item), and its contents aren't going to depend on anything intrinsic to the click event (like which .showdiv you clicked). In the former example it will however fail to show anything until the first click (after which you would have to reset with Session.set('vname', null) to stop it showing anything again).

Attaching jQuery plugins to Meteor template-generated DOM elements

According to the Meteor documentation, a callback assigned to Template.template_name.rendered will execute after each instance of template_name has finished rendering. I have been trying to use this feature to attach jQuery plugins (such as TagsManager or DotDotDot) to DOM elements generated by the templates. The "natural" way to do this would be something like:
Template.template_name.rendered = function () {
var template = this;
var elem = $('input#tags'+template.data._id);
elem.tagsManager(); // doesn't work
}
However, this does not work -- the expected behaviors do not come out attached to the element. The jQuery selector works properly and, by logging the internals of tagsManager(), I can see that the event handlers do seem to get attached, but after .tagsManager() finishes up, they are somehow unattached.
The "usual" solutions of wrapping the code in a $(document).ready or a short setTimeout suffer from the exact same behavior:
Template.template_name.rendered = function () {
var template = this;
$(document).ready(function () {
window.setTimeout(function () {
var elem = $('input#tags'+template.data._id);
elem.tagsManager();
}, 100); // 0.1 seconds + $(document).ready doesn't work
});
}
I only got it to work by giving an unrealistically high setTimeout time, such as 3 seconds:
Template.song.rendered = function () {
var template = this;
console.log("Template for "+template.data.title+" created");
$(document).ready(function () {
window.setTimeout(function () {
var elem = $('input#tags'+template.data._id);
elem.tagsManager();
}, 3000); // 3 seconds + $(document).ready works
});
}
As a matter of fact, even replacing elem.tagsManager() by a simple elem.on('click',...) suffers from the same behaviors as described above -- which is why the guys at Meteor have given us Template.template_name.events, I guess. However, this kind of breaks all interesting plugins, and forces us to rely on hacky, dangerous code such as the above. Is there a better way?
In the template, wrap the div you want to apply the jQuery with {{#constant}} helper. This will kill all reactivity you may have on elements wrapped up.
If you need reactivity or constant did not help, try this hack. I unbind the event of the element when rendered is called and bind it right after. The problem in this case is that rendered is called like a dozen times and it screw up some way I haven't figured out. Try debugging it to see how many it is called with console.log in the first line of rendered.
Hope it helps!
check that package : https://github.com/Rebolon/meteor-animation/blob/master/meteor-animation-client.js
line 38 to 56
it uses template.rendered with a cursor observer.
It might help you coz it also uses jquery.

how to properly bind jquery ui behaviors in meteor?

I am trying to create a group of draggable DOM objects using jQuery UI's .draggable() that are populated through Meteor subscriptions. The code I came up with looks like
Meteor.subscribe('those_absent', function() {
$( "li.ui-draggable" ).draggable( { revert: "invalid" } );
});
Meteor.subscribe('those_present', function() {
$( "li.ui-draggable" ).draggable( { revert: "invalid" } );
});
These correspond with some Meteor.publish() calls, so that any time the collection changes, the .draggable() behaviour will be attached. At least, that was my intention.
However, it only works once - once one of these <li>'s has been dragged and dropped, then they are no longer draggable at all.
When the objects are dropped, I'm firing a custom event that is attached to the Template for the item like so
$( "#c_absent .inner-drop" ).droppable({
drop: function( event, ui ) {
ui.draggable.trigger('inout.leave');
}
});
Template.loftie_detail.events = {
'inout.leave': function (e) {
Lofties.update({_id:this._id}, {$set: {present: 'N' }});
}
};
So, my thinking is that this change to the collection on drop should propagate through the pub/sub process and re-run the .draggable() line above. But it doesn't seem to.
The complete code for this can be seen here https://github.com/sbeam/in-out/blob/master/client/inout.js and the app is live at http://inout.meteor.com/ (there are some other probably unrelated issues with items randomly losing values or disappearing from the UI altogether)
So if my understanding of how pub/sub works in Meteor is off, it would be good to know. Or is there a more efficient way to achieve this UI behavior binding that works without it?
The way I have implemented this in my apps is with the method shown by #lashleigh.
I have a template event that listens using code like this :
Template.myDraggableItem.events({
'mouseover .workItem' : function() {
$(this._id).draggable();
}
});
Then I listen for the dragstop like this.
$('body').on('dragstop', '.myDraggableItem', function (e) {
// Update the collection with the new position
};
You can see the app that's using this code at aduno.meteor.com

FullCalendar is inserting duplicate events even when removing all events

FullCalendar is working great apart from 1 issue I'm having.
The monthview div which loads a calendar in monthview mode, seems to show duplicate holidays loaded in. This happens when I add an event, and then call my calendar bind function, which basically runs the code below.
Has anyone else had a similar issue? It looks like 'removeEvents' function is working ok against the data feed which comes from an internal database, but seems to leave the google dates. When the addEventSource is called, it's adding the same events again.
var googleUkHolidaysFeed = {
url: 'http://www.google.com/calendar/feeds/uk__en%40holiday.calendar.google.com/public/basic',
cache: true,
color: "green"
};
$.getJSON(url, {}, function (data) {
$('#dayview').fullCalendar('removeEvents');
$('#dayview').fullCalendar('addEventSource', data);
if ($("#monthview")[0]) {
$('#monthview').fullCalendar('removeEvents');
$('#monthview').fullCalendar('addEventSource', data);
$('#monthview').fullCalendar('addEventSource', googleUkHolidaysFeed);
}
});
I resolved this issue myself. The 'removeEvents' has to be called followed by 'removeEventSource' like so:
('data' is json array of events provided by the app, 'googleCalendarUkHolidayFeed' is the url feed from google).
var googleCalendarUkHolidayFeed = {
url: "http://www.google.com/calendar/feeds/bla..."
}
$('#dayview').fullCalendar('removeEvents');
$('#dayview').fullCalendar('addEventSource', data);
if ($("#monthview")[0]) {
// remove events and re-add event source to reflect search/non-search
$('#monthview').fullCalendar('removeEvents');
$('#monthview').fullCalendar('removeEventSource', googleCalendarUkHolidayFeed);
$('#monthview').fullCalendar('removeEventSource', data);
$('#monthview').fullCalendar('addEventSource', googleCalendarUkHolidayFeed);
$('#monthview').fullCalendar('addEventSource', data);
}

Resources