Meteor - iron-router not waiting on subscription data in onBeforeAction hook

笑着哭i 提交于 2019-12-08 04:11:17

问题


I want to set a Session variable (artistNotAvailable) when the requested artist is not available. Unfortunately, the route does not work, because it is not waiting on subscription data in my onBeforeAction hook. artistAvail and artist is undefined, but not because there is no artist in the DB, I think it is a subscription problem. I debugged it and calling Artists.find().fetch(); in the browsers console returned undefined.

Here is my route:

this.route('eventPage', {
        path: '/event/:slug/:openDate?/:closeDate?',
        onBeforeAction: [teamFilter, function() {
            var event = this.data();
            if (event.outdoor) {
                this.subscribe('artists', this.params.slug);
                if (this.ready()) {
                    var artistAvail = Artists.findOne({eventId: event._id, openDate: moment(this.params.openDate).toDate(), closeDate: moment(this.params.closeDate).toDate()});
                    if ((!this.params.openDate && !this.params.closeDate) || typeof artistAvail === "undefined") {
                        var artist = Artists.findOne({
                            eventId: event._id,
                            openDate: {$lte: new Date()},
                            closeDate: {$gte: new Date()}
                        });
                        if (Artists.find().count() > 0 && artist) {
                            Session.set('artistNotAvailable', true);
                            this.redirect('eventPage', {
                                slug: this.params.slug,
                                openDate: moment(artist.openDate).format('YYYY-MM-DD'),
                                closeDate: moment(artist.closeDate).format('YYYY-MM-DD')
                            });
                        } else {
                            Session.set('noArtists', true);
                            this.redirect('overviewPage', {slug: this.params.slug});
                        }
                    } else {
                        this.subscribe('musicOutdoor', this.params.slug, moment(this.params.openDate).toDate(), moment(this.params.closeDate).toDate());
                        if (this.ready()) {
                            var guestsIds = new Array();
                            Guests.find({artistId: artistAvail._id}).forEach(function (guest) {
                                guestIds.push(guest._id);
                            });
                            this.subscribe('guestsOutdoor', guestIds);
                        } else {
                            this.render('loading');
                        }
                    }
                } else {
                    this.render('loading');
                }
            } else {
                this.subscribe('musicIndoor', this.params.slug);
                this.subscribe('guestsIndoor', this.params.slug);
                if (!this.ready()) {
                    this.render('loading');
                }
                this.next();
            }
            this.next();
        }],
        waitOn: function() { return [Meteor.subscribe('singleEvent', this.params.slug)]; },
        data: function() {
            return Events.findOne({slug: this.params.slug});
        }
    });

Subscription:

Meteor.publish('artists', function(slug) {
    var event = Events.findOne({slug: slug});
    if (event) {
        return Artists.find({eventId: event._id});
    } else {
        return null;
    }
}); 

Now the problem is that when I access the eventPage with a wrong openDate or closeDate I will be redirected to the overviewPage, even though there are artists in the db. As already mentioned, I debugged it and it seems to be that this.ready() is not working. I really miss .wait() :-(

Any help would be greatly appreciated.


回答1:


Iron Router works fine.

this.subscribe is like Meteor.subscribe and Iron-Router doesn't wait for this.

waitOn is the function that will wait until each of your returned subscriptions are ready that is why this.ready() is true in onBeforeAction

There are several ways of doing what you want

  • You could do it like CodeChimp said by using templates with create/destroyed
  • You could split your route in different routes so that you redirect when it's needed
  • you could use .wait() from the new API of iron router here.



回答2:


It helped me to wait for the subscribing (until the subscription is really ready) in data function, like this:

Router.route('/:_id', {
    name: 'show',
    template: 'show',
    waitOn: function () {

        var id = this.params._id;
        return Meteor.subscribe('something', id, {});
    },
    data: function () {

        if (this.ready()) {
            var id = this.params._id;
            var data = Somethings.findOne({_id: id});
            return data;
        }
    }
});


来源:https://stackoverflow.com/questions/26939956/meteor-iron-router-not-waiting-on-subscription-data-in-onbeforeaction-hook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!