AngularJs - RXJS Observable unsubscribe

15,166

Solution 1

Please see updated fiddle: here

the subscribe function returns a Disposable to work with and you must first return the subscription from your factory (line 60):

subscribe: function(subscription){
    return msgSubject.subscribe(subscription);
}

This will let you store your subscription in each controller to work with in the future. (line 21 & 42)

var boxASubscription = boxA.msgService.subscribe(function(obj) {
    console.log('Listerner A');
    boxA.msg = obj;
});

You can then call the dispose method on the subscription when you want to unsubscribe:

boxA.unsubscribe = function(){
    console.log('Unsubscribe A');
    boxASubscription.dispose();
};

n.b.

For some reason I couldn't get your demo to work with <md-button> so I changed this to <button> for the sake of the demo.

Solution 2

As per my comment above the new RxJs 5 Beta now changed from subscription.dispose() to subscription.unsubscribe() Please refer to here https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md#subscription-dispose-is-now-unsubscribe

Share:
15,166
Ka Tech
Author by

Ka Tech

Updated on July 28, 2022

Comments

  • Ka Tech
    Ka Tech over 1 year

    I have setup an RXJS observable. I have two components which subscribe to a subject in service factory. How do I unsubscribe a selected component to the subject so that a button is pressed it stops listening to the subject broadcast?

    See my jsfiddle Unsubscribe App

    My code:

    <div ng-app="myApp" ng-controller="mainCtrl">
    
      <script type="text/ng-template" id="/boxa">
      BoxA - Message Listener: </br>
      <strong>{{boxA.msg}}</strong></br>
      <md-button ng-click='boxA.unsubcribe()' class='md-warn'>Unsubscribe A</md-button>
      </script>
      <script type="text/ng-template" id="/boxb">
        BoxB - Message Listener: </br>
      <strong>{{boxB.msg}}</strong></br>
      <md-button ng-click='boxB.unsubcribe()' class='md-warn'>Unsubscribe B</md-button>
     </script>
    
      <md-content class='md-padding'>
        <h3>
          {{name}}
        </h3>
        <label>Enter Text To Broadcast</label>
        <input ng-model='msg'/></br>
        <md-button class='md-primary' ng-click='broadcastFn()'>Broadcast</md-button></br>
        <h4>
        Components
        </h4>
        <box-a></box-a></br>
        <box-b></box-b>
      </md-content>
    
    </div><!--end app-->
    
    
    var app = angular.module('myApp', ['ngMaterial']);
    app.controller('mainCtrl', function($scope,msgService) {
    
       $scope.name = "Observer App Example";
       $scope.msg = 'Message';
       $scope.broadcastFn = function(){
            msgService.broadcast($scope.msg);
       }   
    });
    
    app.component("boxA",  {
          bindings: {},
          controller: function(msgService) {
            var boxA = this;
            boxA.msgService = msgService;            
            boxA.msg = '';
            boxA.msgService.subscribe(function(obj) { 
                console.log('Listerner A');
              boxA.msg = obj;
                    });
            boxA.unsubscribe=function(){
    
            };
    
          },
          controllerAs: 'boxA',
          templateUrl: "/boxa"
    })
    app.component("boxB",  {
          bindings: {},
          controller: function(msgService) {
            var boxB = this;
            boxB.msgService = msgService;            
            boxB.msg = '';
            boxB.msgService.subscribe(function(obj) { 
                console.log('Listerner B');
              boxB.msg = obj;
                    });
    
            boxB.unsubscribe=function(){
    
            };
          },
          controllerAs: 'boxB',
          templateUrl: "/boxb"
    })
    
    app.factory('msgService', ['$http', function($http){
        var msgSubject = new Rx.ReplaySubject();
        return{
            subscribe:function(subscription){
                msgSubject.subscribe(subscription);
            },
            broadcast:function(msg){
            console.log('success');
                msgSubject.onNext(msg);
            }
        }   
    }])