Abdul Hameed
Abdul Hameed

Reputation: 938

Strange behavior on route change

i am facing strange meteor behavior in collection subscribing. i am have one abstract route mailbox and have three route beneath this. Inbox, sent, and singleMail (which is showing details of one mail from both). now the issue is when i resolve the mails collection in single mail route it bind the same mails collection for both inbox and sent, despite am publishing different collection for both. Note : it working perfect until am go to single mail route from both. eg when i click on any mail from inbox or sent it will go to single mail route and show the details of email. and when back. from here the problem starts. it subscribe the mails collection for both. i.e if inbox has 6 and sent has 3 it will show 9 for both. i tried hours but no luck there. Any help is greatly appreciated ! i am pasting much code to address my exact issue. here is mail.js in server

Meteor.publish("mails", function (obj) {

    //Will use for admin
    isAuth(this);

    var query = {identity:this.userId};
    if (obj) {
        query[obj.condition] = obj.id;
    }
    return Mails.find(query);

});

Meteor.publish("mailsTo", function (options) {
    //if user not logged in
    isAuth(this);
    Counts.publish(this, 'countOfNewMails', Mails.find({identity: this.userId, 'to.id': this.userId, unread: true}));
    Counts.publish(this, 'countOfToMails', Mails.find({identity: this.userId, 'to.id': this.userId}), { noReady: true });
    return Mails.find({identity: this.userId, 'to.id': this.userId}, options);
});

Meteor.publish("mailsFrom", function (options) {
    //if user not logged in
    isAuth(this);
    Counts.publish(this, 'countOfFromMails', Mails.find({identity: this.userId, from: this.userId}), { noReady: true });
    return Mails.find({identity: this.userId, from: this.userId}, options);
});

Here is my route.js

angular.module('Secret')
    .config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
        function($urlRouterProvider, $stateProvider, $locationProvider){

            $locationProvider.html5Mode(true);

            $stateProvider
                .state('home', {
                    url: '/home',
                    templateUrl: 'client/home/views/home.ng.html',
                    controller: 'homeCtrl'
                })
                .state('login', {
                    url: '/homes/:id/login',
                    templateUrl: 'client/login/views/login.ng.html',
                    controller: 'loginCtrl'
                })
                .state('signup', {
                    url: '/homes/:id/signup',
                    templateUrl: 'client/signup/views/signup.ng.html',
                    controller: 'signupCtrl'
                })
                .state('forgotPassword', {
                    url: '/homes/:id/forgot-password',
                    templateUrl: 'client/forgotPassword/views/forgotPassword.ng.html',
                    controller: 'forgotPasswordCtrl'
                })
                .state('profile', {
                    url: '/profile',
                    templateUrl: 'client/profile/views/profile.ng.html',
                    controller: 'profile'
                })
                .state('mailbox', {
                    url: '/mailbox',
                    templateUrl: 'client/mailBox/views/mailbox.ng.html',
                    controller: 'mailboxCtrl',
                    abstract: true
                })
                .state('mailbox.inbox', {
                    url: '/inbox',
                    templateUrl: 'client/inbox/views/inbox.ng.html',
                    controller: 'inboxCtrl',
                    resolve: {
                        "currentUser": ["$meteor", function($meteor){
                            return $meteor.requireUser();
                        }]
                    }
                })
                .state('mailbox.sent', {
                    url: '/sent',
                    templateUrl: 'client/sent/views/sent.ng.html',
                    controller: 'sentCtrl'
                })
                .state('mailbox.singleMail', {
                    url: '/:folder/:id',
                    params: {
                        hasnext: null
                    },
                    templateUrl: 'client/singleMail/views/single.ng.html',
                    controller: 'singleCtrl',
                    resolve: {
                        "currentUser": ["$meteor", function($meteor){
                            return $meteor.requireUser();
                        }],
                        statesSub: ['$meteor', '$stateParams', function($meteor, $stateParams) {
                            return $meteor.subscribe('mails', $stateParams.id);
                        }]
                    }
                })
                .state('mailbox.compose', {
                    url: '/compose/:r/:mailId',
                    templateUrl: 'client/compose/views/compose.ng.html',
                    controller: 'composeCtrl'
                })

            $urlRouterProvider.otherwise("/home");

        }])
    .run(['$rootScope', '$state',
        function($rootScope, $state){
        $rootScope.$on("$stateChangeError", function(event, next, previous, error) {
            // We can catch the error thrown when the $requireUser promise is rejected
            // and redirect the user back to the main page
            //if (error === "AUTH_REQUIRED") {
                $state.go("home");
            //}
        });
    }]);

and in controllers as simple SentCtrl

$scope.page = 1;
        $scope.perPage = 50;
        $scope.sort = { createdAt: -1 };

        //get reactively
        $meteor.autorun($scope, function() {
            $scope.mails = $scope.$meteorCollection(Mails).subscribe('mailsFrom',{
                limit: parseInt($scope.getReactively('perPage')),
                skip: (parseInt($scope.getReactively('page')) - 1) * parseInt($scope.getReactively('perPage')),
                sort: $scope.getReactively('sort')
            })
        })

InboxCtrl

$scope.page = 1;
    $scope.perPage = 50;
    $scope.sort = { createdAt: -1 };

    $scope.pagechanged = function(sign){
        sign ? $scope.page++ : $scope.page--;
    }

    //get reactively
    $meteor.autorun($scope, function() {
        $scope.inbox = $scope.$meteorCollection(Mails).subscribe('mailsTo',{
            limit: parseInt($scope.getReactively('perPage')),
            skip: (parseInt($scope.getReactively('page')) - 1) * parseInt($scope.getReactively('perPage')),
            sort: $scope.getReactively('sort')
        })
    })

and in single mail am just getting mail by params

$scope.currentMail = $meteor.object(Mails, $stateParams.id);

Upvotes: 4

Views: 111

Answers (1)

Whenever you subscribe a collection, you got the subscription handle for this. So you can stop it when template destroyed. (i.e. subscription_handle.stop()) on template.destroyed() in meteor angular context.

Upvotes: 4

Related Questions