Search code examples
meteorcollectionsroutesiron-router

Adding collection items as routes in Meteor


I have a meteor project where all my users have their own profile page setup in this way using routes:

Routes code:

Router.route('/@:username', {
  name: 'profile',
  controller: 'ProfileController'
});

ProfileController = RouteController.extend({
  template: 'profile',
  waitOn: function() {
    return Meteor.subscribe('userProfile', this.params.username);
  },
  data: function() {
    var username = Router.current().params.username;
    return Meteor.users.findOne({
      username: username
    });
  }
});

Server code:

Meteor.publish('users', function() {
  return Meteor.users.find({}, {fields: {username: 1, emails: 1, profile: 1, roles: 1}});
});

Meteor.publish('userProfile', function(username) {
  // Try to find the user by username
  var user = Meteor.users.findOne({
    username: username
  });
  // If we can't find it, mark the subscription as ready and quit
  if (!user) {
    this.ready();
    return;
  }
  // If the user we want to display the profile is the currently logged in user
  if(this.userId === user._id) {
    // Then we return the curresonding full document via a cursor
    return Meteor.users.find(this.userId);
  } else {

    return Meteor.users.find(user._id, {
      fields: {
        profile: 0
      }
    });
  }
});

I want to do something similar with a pages collection that I've set up. Creating the collection works and the collection page has an _id field that is made upon creation.

Right now the program works nicely for users where mysite.com/@ works. Now I want the same thing to work for mysite.com/&

I've basically attempted to do the exact same thing as I did in the above code with the user name but it wasn't working. I've checked to make sure my creation of the collection items are working and they are. But somehow I can't figure out how to do this same thing with collections since I'm relatively new to using routes.

This is what I've attempted:

Here's my routes:

var pageRoute = '/&:_id';
Router.route(pageRoute, {
  name: 'page',
  controller: 'PageController'
});

PageController = RouteController.extend({
  template: 'page',
  waitOn: function() {
    return Meteor.subscribe('Page', this.params._id);
  },
  data: function() {
    var _id = Router.current().params._id;
    return Meteor.pages.findOne({
      _id: _id
    });
  }
});

Server code:

Meteor.publish('pages', function() {
  return Pages.find({});
});

Meteor.publish('Page', function(_id) {
  // Try find the page by _id
  var page = Meteor.pages.findOne({
    _id: _id
  });
  // If we can't find it, mark the subscription as ready and quit
  if (!page) {
    this.ready();
    return;
  }
  // If the page we want to display is not claimed, display it
  if(true) {
    return Meteor.pages.find(this._id);
  } else {
    // Redirect to the page
  }
});

The Schema of the Page Collection:

_id: , createdAt: , CreatedBy: , claimedAt: , claimedBy: ,

Update:

I've scoped it down to this problem, I get the following error in the console server-side:

I20160202-11:16:24.644(2)? Exception from sub qrPage id 2kY6RKCTuCpBDbuzm TypeError: Cannot call method 'findOne' of undefined
I20160202-11:16:24.645(2)?     at [object Object].process.env.MAIL_URL [as _handler] (server/ecclesia.life_server.js:40:33)
I20160202-11:16:24.645(2)?     at maybeAuditArgumentChecks (livedata_server.js:1698:12)
I20160202-11:16:24.645(2)?     at [object Object]._.extend._runHandler (livedata_server.js:1023:17)
I20160202-11:16:24.645(2)?     at [object Object]._.extend._startSubscription (livedata_server.js:842:9)
I20160202-11:16:24.646(2)?     at [object Object]._.extend.protocol_handlers.sub (livedata_server.js:614:12)  
I20160202-11:16:24.646(2)?     at livedata_server.js:548:43                                                   

This error occurs whenever I try to direct to mysite.com/&<_id>


Solution

  • This got it working...

    Publications:

    Meteor.publish('qrpages', function() {
      return QRPages.find({});
    });
    
    Meteor.publish('qrPage', function(id) {
      // Try find the qrpage by _id
      var qrpage = QRPages.find({_id: id});
      // If we can't find it, mark the subscription as ready and quit
      if (!qrpage) {
        this.ready();
        return;
      }
      return qrpage;
    });
    

    Routes:

    var qrpageRoute = '/$:_id';
    Router.route(qrpageRoute, {
      name: 'qrpage',
      controller: 'QRController'
    });
    
    QRController = RouteController.extend({
      template: 'qrpage',
      waitOn: function() {
        var id = this.params._id;
        return Meteor.subscribe('qrPage', id);
      },
      data: function() {
        var id = this.params._id;
        return QRPages.findOne({
          _id: id
        });
      }
    });