li-raz
li-raz

Reputation: 1696

AngularJS with SignalR

I am playing with Angular and SignalR, I have tried to create a service which will act as a manager.

dashboard.factory('notificationsHub', function ($scope) {
  var connection;
  var proxy;

  var initialize = function () {
    connection = $.hubConnection();
    proxy = connection.createHubProxy('notification');

    proxy.on('numberOfIncidents', function (numOfIncident) {
      console.log(numOfIncident);
      $scope.$emit('numberOfIncidents', numOfIncident);
    });

    connection.start()
      .done(function() {
        console.log('Connected');
      })
     .fail(function() { console.log('Failed to connect Connected'); });
  };

  return {
    initialize: initialize
  };
});

however I get the error Error: Unknown provider: $scopeProvider <- $scope <- notificationsHub.

How can I use pubsub to pass all the notifications to the controllers? jQuery maybe?

Upvotes: 13

Views: 22046

Answers (4)

Konstantin Zolin
Konstantin Zolin

Reputation: 487

I tried to use $apply() after changing value, i tried to use $apply(functuin() {value = 3}), and also i tried to use $emit and $broadcast for changing value and it doesn't help. But i found solution we need in html after in controller you can use

var scope2 = angular.element("#test").scope();
    scope2.point.WarmData.push(result);
    $scope.$apply();

P.s. I understand that it is very old question, but may by smb, as i, need this solution.

Upvotes: 0

hlovdal
hlovdal

Reputation: 28180

As already noted in johlrich's answer, $scope is not avaliable inside proxy.on. However, just switching to $rootScope will most likely not work. The reason for this is because the event handlers regisrered with proxy.on are called by code outside the angular framework, and thus angular will not detect changes to variables. The same applies to $rootScope.$on event handlers that are triggered by events broadcasted from the SignalR event handlers. See https://docs.angularjs.org/error/$rootScope/inprog for some more details.

Thus you want to call $rootScope.$apply() from the SignalR event handler, either explicitly

proxy.on('numberOfIncidents', function (numOfIncident) {
  console.log(numOfIncident);
  $scope.$apply(function () {
    $rootScope.$emit('numberOfIncidents', numOfIncident);
  });
});

or possibly implicitly through $timeout

proxy.on('numberOfIncidents', function (numOfIncident) {
  console.log(numOfIncident);
  $timeout(function () {
    $rootScope.$emit('numberOfIncidents', numOfIncident);
  }, 0);
});

Upvotes: 1

Jason Capriotti
Jason Capriotti

Reputation: 2060

Here is a great example showing how to wrap the proxy in a service and use $rootScope for event pub/sub.

http://sravi-kiran.blogspot.com/2013/09/ABetterWayOfUsingAspNetSignalRWithAngularJs.html

Upvotes: 3

johlrich
johlrich

Reputation: 1781

$scope does not exist in this context as that's something injected when a controller is created and a new child scope is made. However, $rootScope is available at the time you need.

Also, be aware $emit() goes upward and your controller scopes wont see it. You would either need to switch to $broadcast() so the event goes downwards or inject $rootScope as well to the controllers you want to be able to subscribe to 'numberOfIncidents'

Check out the angular docs and a useful wiki on scopes.

Upvotes: 5

Related Questions