A J Qarshi
A J Qarshi

Reputation: 2992

Scope variable in AngularJS controller not cleared on revisiting the view

I am writing an AngularJS client application which communicates with SignalR 2.2. The Angular application also uses Angular UI Router library.

My hub class looks like:

MessagingHub.cs

public class MessagingHub : Hub
{
    public void Connect()
    {
        Clients.Caller.connected();
    }

}

The main app module is given below:

app.js

(function () {
    'use strict';
    angular.module('app', ['ui.router']);

    //Global error handler for the signalR
    $.connection.hub.error(function (err) {
        console.log('An error occurred: ' + err);
    })
    //Make signalR proxy as a service available to other components.
    angular.module('app').value('message', $.connection.messagingHub);


    angular.module('app').config(function ($stateProvider, $urlRouterProvider) {

        // For any unmatched url, send to /contact
        $urlRouterProvider.otherwise("/contact");

        $stateProvider
          .state('contact', {
              url: "/contact",
              templateUrl: "/app/contact.html"
          })
            .state('messaging', {
                url: "/messaging",
                templateUrl: "/app/messaging.html"
            })

          .state('about', {
              url: "/about",
              templateUrl: "/app/about.html"
          });

    });

})();

contact.html and about.html files contain nothing apart from some headings.

messaging.html is given below:

messaging.html

<div ng-controller="messaging as vm">
    <h1>Messaging</h1>
    <div ng-show="vm.isConnected"><p class="label label-primary">Welcome...</p></div>
    <div ng-show="vm.isAvailable"><p class="label label-info">Your status is available now</p></div>
    <br />
    <br />
    <button class="btn btn-sm btn-primary" ng-click="vm.onStartMessaging()">Connect</button>

</div>

and the corresponding controller is given below:

messaging.js

(function () {
    'use strict';

    angular
        .module('app')
        .controller('messaging', ['$scope', '$timeout','message', messaging]);    

    function messaging($scope, $timeout, message) {
        var vm = this;

        vm.isConnected = false;
        vm.isAvailable = false;
        vm.onStartMessaging = onStartMessaging;
        message.client.connected = onConnected;

        function onStartMessaging() {
            $.connection.hub.logging = true;
            $.connection.hub.start().done(function () {                
                message.server.connect();
                $timeout(function () {
                    vm.isConnected = true;                    
                });
            });
        }

        function onConnected() {                            
            vm.isAvailable = true;   
            $scope.$apply();
        }
    }
})();

when I first go to "Messaging" view and click 'Connect' button, it calls the Connect function on the Hub which then calls connected function on the caller. The handler function in my Angular controller sets vm.isAvailable = true which in turn shows a lebel on the view.

Everything works fine but when I move to other view and come back and click the 'Connect' button again, same process goes through as mentioned above but in the onConnected() javascript function the value of vm.isAvailable is already set to true so the label is not displayed at all which is odd.

Can anybody help me to understand why this is happening and what options do I have.

Upvotes: 0

Views: 245

Answers (1)

A J Qarshi
A J Qarshi

Reputation: 2992

I found the solution for this problem. The only thing I had to do was to handle the state change event for the ui router and close the connection with SignalR hub like below:

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ 
    $.connection.hub.stop();
});

Now it really makes sense to close the hub connection when the user navigates away from the messaging view but why the vm.isAvailable is not set to false on revisiting the view if the SignalR hub connection was not closed when the user navigated away is still a mystery for me. If someone knows the answer to this and can give me some logical reason I will accept the answer.

Upvotes: 2

Related Questions