Search code examples
angularjsangularjs-scopeangularjs-service

$rootScope in angular document ready


I have this piece of code:

.service('webSocket', function ($rootScope, socketFactory, CONFIG, $timeout) {
    angular.element(document).ready(function () {
        $rootScope.log('Waiting for connection...',CONSOLE_INFO);
    });

And I am getting this error:

TypeError: $rootScope.log is not a function

This service is injected into this controller:

.controller('mainCtrl', function mainCtrl($scope, $rootScope, webSocket, myConsole ...

In which I have:

$rootScope.log = function (msg, type) { myConsole.log(msg,type); ... };

Can you tell me where is the problem? Or at least point me in the right direction? The reason I am using document ready function is because apart from logging messages to browser console (console.log) I use notifications for user (pNotify library) which needs to be called after DOM is loaded.


Solution

  • Sharing something between services using $rootScope should be considered generally as anti-pattern. If you don't have some different implementation of console for different controllers, you can do it Angular-way and perform all configurations in config block. Subscribing to document ready event in the service is also not a good idea (I would prefer to do it in run block), since in angular service is instantiated once it is first time required by any other service or controller or whatever. In order to have configurable service that may have different console implementation I would implement it using provider as follows:

    angular.module('app',[]).
      constant('console', console).
      constant('PNotify', PNotify).
      provider('myConsole', function() {
        var log = angular.noop;
        function MyConsoleFactory() {
          return {
            log: log,
            debug: log
          }
        }
        this.setLog = function(logImplementation) {
          log = logImplementation
        }
        this.$get = [MyConsoleFactory];
      }).
      config(['myConsoleProvider', 'console', 'PNotify', function(myConsoleProvider, console, PNotify) {
        myConsoleProvider.setLog(function(msg) {
          console.log('[LOG] '+ Date.now() + ':\t' + msg);
          new PNotify({
            title: 'Title',
            text: msg
          });
        });
      }]).
      run(['myConsole', '$document', function(myConsole, $document) {
        $document.ready(function () {
          myConsole.log('Waiting for connection...');
        });
      }]);
    

    In this case you don't need any controller at all.

    Plunker: http://plnkr.co/edit/aV9TIO07pnDs26xDBPtf?p=preview