How to use $broadcast(), $Emit() and $on() in Angularjs

Asked

Viewed 5,709 times

6

I understood that the $emit() and the $broadcast are emitters and the $on is an event manager. I am working with unit tests and am unable to access the following function:

eventHandler.service.js

(function () {
'use strict';

angular.module("app")

    .service('EventHandler', EventHandler);

EventHandler.$inject = ['$rootScope', '$location', '$animate', '$state', '$stateParams', '$sanitize', '$q', '$uibModal', 'toastr',
    'storage', 'StorageService', 'LogService', 'LanguageResource', 'LoginService', 'StcpUtilsService', 'DAOService',
    'CSRF', 'Authorization', 'ShortcutService', 'data_login', 'PermissionsService', 'BusinessLogicService', 'DebugMode'
]; 

function EventHandler($rootScope, $location, $animate, $state, $stateParams, $sanitize, $q, $uibModal, toastr, storage, StorageService,
                      LogService, LanguageResource, LoginService, StcpUtilsService, DAOService, CSRF,
                      Authorization, ShortcutService, data_login, PermissionsService, BusinessLogicService, Debug) {

    var animate;
    /* = parameters.$animate || $animate; */
    var rootScope;
    /* = parameters.$rootScope || $rootScope; */
    var scope;
    /* = parameters.$scope; */
    var _toastr;
    /* = parameters.toastr || toastr; */
    var _storage;
    /* = parameters.StorageService || StorageService; */
    var location;
    /* = parameters.$location || $location; */
    var log;
    /* = parameters.LogService ? parameters.LogService.log : LogService.log || LogService.log; */
    var language;
    /* = parameters.LanguageResource || LanguageResource; */
    var shortcut;
    var t;
    var dao;
    var DebugMode;

    return {
        initialize: initialize_component,
        onCheckSession: onCheckSessionHandle,
        onLogin: onLoginHandle,
        onLogout: onLogoutHandle,
        onStateChangeError: onStateChangeErrorHandle,
        onHideMenuCheck: onHideMenuCheckHandle,
        onSetInstance: onSetInstanceHandle,
        onRemoveInstance: onRemoveInstanceHandle,
        onGetInstanceName: onGetInstanceNameHandle,
        onGetInstanceId: onGetInstanceIdHandle,
        onGetOperatorLogged: onGetOperatorLoggedHandle,
        onOperatorIsLogged: onOperatorIsLoggedHandle,
        onShakeMenu: onShakeMenuHandle,
        onCheckInstance: onCheckInstanceHandle,
        onSave: onSaveHandle,
        onDelete: onDeleteHandle,
        onInterceptError: onInterceptErrorHandle,
        onChangeOperatorPassword: onChangePasswordHandle,
        onGetTransfer: onGetTransferHandle,
        onOpenChangeModuleDialog: onOpenChangeModuleDialogHandle,
        onChangeSubModule: onChangeSubModuleHandle,
        onDisplaySelectionInstance: onDisplaySelectionInstanceHandle,
        onGetInstances: onGetInstancesHandle,
        onCheckModule: onCheckModuleHandle,
        // onDataToPersist: onDataToPersistHandle
    };

    // function onDataToPersistHandle() { rootScope.$on('dataToPersist', onDataToPersist); }
    function onRemoveInstanceHandle() {
        rootScope.$on('removeInstance', onRemoveInstance);
    }        

    function onRemoveInstance(ev, args) {
        onCheckSession(ev, args);

        if (ev.defaultPrevented === false) {
            _storage[storage].del("instance_id");
            _storage[storage].del("instance_name");
            _storage.local.del("instance_name");
            _storage.local.del("instanceSelected");
            _storage.session.del("instanceSelected");
            rootScope.instanceSelected = undefined;
            delete rootScope.displaySelectionInstance;
            delete rootScope.instance_id;
            delete rootScope.instance_name;
        }
    } //...

I am doing the tests as follows, however I can not test the function "onRemoveInstance", I was told to apply some emitter so that I can access it. And I need to know how to make Ev.defaultPrevented false.

testEventHandlerService.Spec.js

describe('Testing EventHandler', function () {
beforeEach(module('app'));

var srv, rootScope, injector, httpBackend, animate, scope, location, loginService, _toastr, _storage, dao, log, language;

beforeEach(inject(function (EventHandler,_$injector_, $rootScope, $httpBackend, $animate, $location, LoginService, toastr, storage, StorageService, LogService, DAOService, LanguageResource) {
  injector = _$injector_;
  srv = EventHandler;
  rootScope = $rootScope;          
  animate = $animate;
  location = $location;
  loginService = LoginService;
  _toastr = toastr;
  _storage = StorageService;
  log = LogService;
  language = LanguageResource;
  dao = DAOService;


  srv.initialize({
      $rootScope: rootScope,
      $animate: animate,
      $scope: $rootScope.$new(),
      $location: location,
      _toastr: toastr,
      _storage: StorageService,
      log: LogService,
      language: LanguageResource,
      dao: DAOService,
  })

//   rootScope.$on('doLogin', null);      
}));    

it('testing if the onRemoveInstance function', function(){  
    srv.ev = {defaultPrevented: false}; //testando para ver se da certo      
    srv.onRemoveInstance();       
    rootScope.$emit('removeInstance', srv.onRemoveInstance); 
});

it('testing if the onChangeSubModule function', function(){        
    srv.onChangeSubModule();       
    rootScope.$emit('changeSubModule', srv.onChangeSubModule);   
});

If possible someone can give me a real-time example on the use of the three?

  • You have to do your function in the "Angular way" of doing, answered right below

  • @Jackson can pass $Scope. $Emit('onRemoveInstance', $Scope.SOMERSET); inside my test iteration?

  • Yes, you can call $Emit('onRemoveInstance') within $on('onRemoveInstance'). But why do you want to do this? You will make an infinite loop.

  • @Jackson I have a service in the Angularjs with the function above and I need to apply a unit test to it. I’ve been trying to call you in a lot of ways, and I can’t access it, and I’ve been told by the mitters that I’m gonna make it. But I’ve never used it and I’m having a hard time

  • with the $emit sure you will. It is a global call. edit the question with the code so I understand better

  • @Jackson the question has been edited. I hope it improves understanding

  • 1

    Okay, from what I’m seeing, you can’t access it because yours $on is encapsulated from a pure javascript function, you need to create the function from the $scope. For example your function => Function onRemoveInstanceHandle() { rootScope. $on('removeInstance', onRemoveInstance); }... Remove all and leave only $Scope.on('removeInstance', onRemoveInstance)

  • If you don’t understand, try adapting a simple plunker with just one call triggering an alert. If it’s not possible, we’ll try another way

  • @Jackson got into the job onRemoveInstance but she’s not checking if. Do you have any idea how I can do this? I was trying to pass as an object as it is in the test case. That’s right?

Show 5 more comments

1 answer

4

The $emit and the $broadcast are very similar. As you said, both are to fire something. I will try to explain very simply

The $broadcast calls the event of everyone who is "below" him, would be the same children. Already the $emit calls every event with that name. He’s a guy who shoots globally.

The $on is the Istener, so it will be activated when it is called by a $emit or $broadcast

I don’t know what you want to do there in your code, but it would be something like that:

$scope.$on('onRemoveInstance', function(ev, args) {
onCheckSession(ev, args);

        if (ev.defaultPrevented === false) {
            _storage[storage].del("instance_id");
            _storage[storage].del("instance_name");
            _storage.local.del("instance_name");
            _storage.local.del("instanceSelected");
            _storage.session.del("instanceSelected");
            rootScope.instanceSelected = undefined;
            delete rootScope.displaySelectionInstance;
            delete rootScope.instance_id;
            delete rootScope.instance_name;
        }
});

// Aqui embaixo eu chamo minha função. Essa minha chamada pode ser feita em qualquer lugar do código, inclusive em outro arquivo javascript em um outro controller.

$scope.$emit('onRemoveInstance', $scope.ALGUMACOISA);

As a request, I am leaving here also this Plunker showing in practice that.

Enjoy and also read about $ROOTSCOPE in the official documentation of Angularjs

Browser other questions tagged

You are not signed in. Login or sign up in order to post.