1

I'm trying to use Meteor to build a calendar app, but having issues about initial loading of data from database.

At the very beginning, I just used the autopublish, which caused the problem because the subscription might not be ready yet. Then I looked at the questions here Can't put data from a Meteor collection into an array and here Meteor: How can I tell when the database is ready? and make some changes of my code to this:

Meteor.startup(function(){
  Session.set("data_loaded", false);
});

Meteor.subscribe("allEvents", function() {
  Session.set("data_loaded", true);
});

var myCalendar = null;

Template.Calendar.onRendered(function() {
  if (Session.get("data_loaded")) {
    myCalendar = $('#myCalendar').fullCalendar({
      header: {
        left: 'prev,next,today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
      },
      defaultView: 'agendaWeek',

      dayClick: function(date, jsEvent, view) {
        CalEvents.insert({title:"New Event", start:date.format(), end:date.format()});
        Session.set("lastMod", new Date());
      },
      eventClick: function(calEvent, jsEvent, view) {

      },
      events: function(start, end, timezone, callback) {
        var events = [];
        allEvents = CalEvents.find({},{reactive:false});
        console.log(allEvents);
        allEvents.forEach(function(evt){
          console.log(evt);
          events.push({
            id:evt._id,
            title:evt.title,
            start:evt.start,
            end:evt.end});
        });
        callback(events);
      }
    }).data().fullCalendar;
  }
  myCalendar.defaultView = 'agendaWeek';
});

Template.Calendar.lastMod = function() {
  return Session.get("lastMod");
};

However, I'm still having the same problem, just at this time, instead of showing a blank calendar, it doesn't show calendar at all in most cases. I feel like I'm not setting Session correctly, especially for that if statement, but I'm not very sure how to do that.

And then, I found this post Displaying loader while meteor collection loads , and followed the step there to make a template-level subscriptions. However, I got another error.

var myCalendar = null;

Template.Calendar.onCreated(function(){
  this.subscribe("allEvents");
});

Template.Calendar.onRendered(function() {
    myCalendar = $('#myCalendar').fullCalendar({
      header: {
        left: 'prev,next,today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
      },
      defaultView: 'agendaWeek',

      dayClick: function(date, jsEvent, view) {
        CalEvents.insert({title:"New Event", start:date.format(), end:date.format()});
        Session.set("lastMod", new Date());
      },
      eventClick: function(calEvent, jsEvent, view) {

      },
      events: function(start, end, timezone, callback) {
        var events = [];
        allEvents = CalEvents.find({},{reactive:false});
        console.log(allEvents);
        allEvents.forEach(function(evt){
          console.log(evt);
          events.push({
            id:evt._id,
            title:evt.title,
            start:evt.start,
            end:evt.end});
        });
        callback(events);
      }
    }).data().fullCalendar;
  myCalendar.defaultView = 'agendaWeek';
});

Template.Calendar.lastMod = function() {
  return Session.get("lastMod");
};

template file:

<template name="Calendar">
  {{#if Template.subscriptionReady}}
    {{> editEvent}}
    <br>
    <br>
    <input type="hidden" name="lastMod" value="{{lastMod}}" id="lastMod">
    <div id="myCalendar">
    </div>
  {{else}}
    Loading...
  {{/if}}
</template>

When the application starts, it shows the "Loading..." characters, but then I got a TypeError: Cannot read property 'fullCalendar' of undefined from }).data().fullCalendar;

Anyone can help me to get this thing work? Thanks in advance.

Community
  • 1
  • 1

1 Answers1

0

Short answer: "meteor search" is your friend. Use the component that I linked in the comment.

Long answer: Getting UI elements to work that modify DOM or create entire DOM trees is tricky with meteor. The overall problem is that meteor doesn't have a single callback which gets called when the DOM is finalized. In fact, DOM is never finalized and could change at any point. Any custom nodes that a UI component created and were in the subtree will get destroyed and will have to be recreated. While it can be done, it is quite a bit of plumbing and isn't easily understood by the newly initiated to meteor.

Luckily however, most of the frequent used UI components already have a meteor smart package and using them is just a matter of doing a "meteor add". Even a bit more experienced ones out of us prefer to simply save time and if a package already have the plumbing of the component sorted out, would just use that instead of spending a few hours trying to get it to work from scratch.

Adnan Y
  • 2,982
  • 1
  • 26
  • 29
  • well I was using https://atmospherejs.com/rzymek/fullcalendar , and seems like most people are using it. I tried the package you provided above, looks like it loads data correctly, but it has very odd display result for week and day view. It only displays the month view correctly. – ethanding555 Apr 22 '15 at 01:36
  • but this still doesn't solve the problem. I tried to remove all the format options when using your package, but it's still not able to provide views for per week or per day. So, the calendar is still not working. And also, I'm still not understand what I'm doing wrong here in my code. – ethanding555 Apr 22 '15 at 01:46
  • There is nothing specifically wrong with the code for a classic web app. Meteor is a different way to write webapps which means that means rethinking what you know about webapps. – Adnan Y Apr 22 '15 at 10:56