[solved] Subscription doesn't work with arguments in iron router route


#1

Dear Meteors,

I am trying to reduce the size of a subscription made from inside an iron router route with an argument passed to the corresponding publish function.

route:

Router.route('/game', {

    layoutTemplate: 'masterLayout',
    yieldRegions: {
      'standardBorder': { to: 'border' },
      'buyMenu': {to: 'buyMenuField'},
      'loading': {to: 'middle'},
    },

    onBeforeAction: function() {
        // some code
        this.next();
    },
    subscriptions: function() {
        var self = Meteor.users.findOne({
              _id: Meteor.userId()
          }, {
              fields: {
                  username: 1,
              }
          }).username;
        if(self) this.subscribe('userDataSelf', self).wait();
        //this.subscribe("userData").wait();                
    },
    action: function() {
        if (this.ready()) {
            this.render();
            var self = Meteor.users.findOne({
                _id: Meteor.userId()
            }, {
                fields: {
                    menu: 1,
                    cu: 1,
                    username: 1
                }
            });
            var cu = self.cu;
            var menu = self.menu;
            if (cu == self.username) {
                Router.current().render(menu + 'Base', {
                    to: 'middle'
                });
            } else {
                Router.current().render(menu + 'Scrounge', {
                    to: 'middle'
                });    
        else {
          Router.current().render('loading', {to: 'middle'});
        }
    }
});

Using the above code I get the expected sub DDP message:

["{\"msg\":\"sub\",\"id\":\"cj2S9HzbpEbYQc6jA\",\"name\":\"userDataSelf\",\"params\":[\"bot20\"]}"]

But there is no document sent, it just readys the sub:

a["{\"msg\":\"ready\",\"subs\":[\"cj2S9HzbpEbYQc6jA\"]}"]

If I switch to using “this.subscribe("userData").wait();” instead of “this.subscribe('userDataSelf', self).wait()” I get DDP messages for all 1000 users in the database.

corresponding publish functions:

Meteor.publish("userDataSelf", function(username) {
        console.log(username);
        if (this.userId) {
            return Meteor.users.find({
                user: username
            }, {
                fields: {
                    'username': 1,
                    'menu': 1,
                    'cu': 1,
                    'x': 1,
                    'y': 1
                }
            });
        } else {
            this.ready();
        }
    });

Meteor.publish("userData", function() {
            if (this.userId) {
                return Meteor.users.find({}, {
                    fields: {
                        'username': 1,
                        'menu': 1,
                        'cu': 1,
                        'x': 1,
                        'y': 1,
                    }
                });
            } else {
                this.ready();
            }
    });

So is it not possible to use subscriptions with arguments inside a route?

Thank you very much in advance. : )


#2
subscriptions: function() {
        var self = Meteor.users.findOne({
              _id: Meteor.userId()
          }, {
              fields: {
                  username: 1,
              }
          }).username;
        if(self) this.subscribe('userDataSelf', self).wait();
        //this.subscribe("userData").wait();                
    },

i think u can use the

,waitOn: function(){
return Meteor.subscribe('userDataSelf', self);
}, data: function() {
return Users.findOne({
              _id: Meteor.userId()});
}

then you also need to create a new collection pointing to the users

Users = new Mongo.collection('users');

#3

Hey, thanks for reading and replying. : )

Unfortunately, following your advice, trying to create the collection results in an error on startup:

  C:\Meteor\Softwareprojekt\Scrounge2>meteor
    [[[[[ C:\Meteor\Softwareprojekt\Scrounge2 ]]]]]
    
    => Started proxy.
    => Started your app.
    
    => App running at: http://localhost:3000/
       Type Control-C twice to stop.
    
    I20150710-10:26:16.950(2)? {}
    C:\Users\Shuyin\AppData\Local\.meteor\packages\meteor-tool\1.1.3\mt-os.windows.x86_32\dev_bundle\server-lib\node_modules\fib
    ers\future.js:245
    throw(ex);
    ^
    
    Error: A method named '/users/insert' is already defined
         at packages/ddp/livedata_server.js:1461:1
         at Function._.each._.forEach (packages/underscore/underscore.js:113:1)
         at [object Object]._.extend.methods (packages/ddp/livedata_server.js:1459:1)
         at [object Object].Mongo.Collection._defineMutationMethods (packages/mongo/collection.js:904:1)
         at new Mongo.Collection (packages/mongo/collection.js:209:1)
         at app\collections.js:12:9
         at app\collections.js:30:3
         at C:\Meteor\Softwareprojekt\Scrounge2\.meteor\local\build\programs\server\boot.js:222:10
         at Array.forEach (native)
         at Function._.each._.forEach (C:\Users\Shuyin\AppData\Local\.meteor\packages\meteor-tool\1.1.3\mt-os.windows.x86_32\dev_
    bundle\server-lib\node_modules\underscore\underscore.js:79:11)

    => Exited with code: 8

#4

The subscriptions option I’m using seems to be new since 0.9.4 (https://github.com/iron-meteor/iron-router)

Shouldn’t it be possible to use this.subscribe() with arguments?

The strange thing is, when I’m checking the passed argument in server.js in the publish function:

Meteor.publish("userDataSelf", function(username) {
        console.log(username);
        if (this.userId) {
            return Meteor.users.find({
                user: username
            }, {
                fields: {
                    'username': 1,
                    'menu': 1,
                    'cu': 1,
                    'x': 1,
                    'y': 1
                }
            });
        } else {
            this.ready();
        }
    });

The desired argument is correctly passed and printed to the console and the DDP sub and ready messages are also sent correctly. Only there is no document sent…


#5

my bad, i think the Users it’s already available at Meteor.users. so we dont need to create another collection object. since it is already availble to accounts-ui.

try Meteor.users.findOne(); in the data just like in ur published.


#6

works : )

and this matter is solved. Thanks. ; )