1

I've decorated the AngularJS $log service, but I can only see it load the config and none of the $log methods are decorated. This used to work and I have a lot of $log.info(...); in the application that I need to be turned off for a deploy, but even with production being set they continue to be logged to console. I abridged the methods decorated down to just info for brevity.

Can anyone see what has happened or is wrong? This is pretty textbook and when I noticed it wasn't working anymore I checked a bunch of sources and they appear to be doing it the same way.

(function () {

    'use strict';

    /**
     * Registers a decorator for the $log service.
     * @param {Object} $provide
     */
    function logConfig($provide) {

        console.log('CAN SEE CONFIG BOOTSTRAP');

        $provide.decorator('$log', extendLogHandler);
    }

    logConfig.$inject = [
        '$provide'
    ];

    /**
     * Turns off logging to the console based on the environment set in the configuration
     * settings as long as logging was performed through AngularJS' $log component.
     * @param {Object} $delegate Service instance of $log to be decorated
     * @param {Object} APP_CONFIG
     * @returns {Object}
     */
    function extendLogHandler($delegate,
                              APP_CONFIG) {

        // Saving the original behaviour
        var _info = $delegate.info;

        // Supplant existing behaviour by stipulating the application must be
        // in development mode in order to log
        $delegate.info = function (msg, data) {

            console.log('NOT INVOKED');

            // Prevent all logging unless in development
            if (APP_CONFIG.ENV !== 'production') {

                // Replace the original behavior
                if (angular.isDefined(data)) {
                    _info(msg, data);
                }
                else {
                    _info(msg);
                }
            }
        };

        // Provide the supplanted $log delegate
        return $delegate;
    }

    extendLogHandler.$inject = [
        '$delegate',
        'APP_CONFIG'
    ];

    angular
        .module('app')
        .config(logConfig);
})();

UPDATE

Seems the issue is related to this other config that scrolls the application to the top when ngTable events occur:

function table(UtilsFactoryProvider,
               ngTableEventsChannelProvider) {

    // Reference to new page generation event listener
    var newPageGenerationListener = null;

    var ngTableEventsChannel = ngTableEventsChannelProvider.$get();
    var UtilsFactory = UtilsFactoryProvider.$get();

    // Subscribe to new instances of NgTableParams
    ngTableEventsChannel
        .onAfterCreated(function () {

            // Set the previous page default for new instance
            var prevPage = null;

            // Deregister the any existing page generation event listener
            if (typeof newPageGenerationListener === 'function') {

                // Release memory to prevent leaks
                newPageGenerationListener();
            }

            // Subscribe to new page generation event listener
            newPageGenerationListener = ngTableEventsChannel
                .onPagesChanged(function (events) {

                    // Set the next page
                    var nextPage = events.page();

                    // Only scroll to the top if not a new instance
                    if (prevPage !== null) {

                        UtilsFactory
                            .scrollTop(true);
                    }

                    prevPage = nextPage;
                });
        });
}

table.$inject = [
    'UtilsFactoryProvider',
    'ngTableEventsChannelProvider'
];
mtpultz
  • 17,267
  • 22
  • 122
  • 201
  • You are using `$log.info()` in your code? – dfsq Feb 10 '17 at 23:17
  • Hi @dfsq. Yah, I'm injecting $log into controllers and invoking `$log.info('...' [, data]);` – mtpultz Feb 10 '17 at 23:21
  • 2
    Can't reproduce: http://plnkr.co/edit/RNcV8K1G4yXLjr5KRsGt?p=preview – dfsq Feb 10 '17 at 23:44
  • Thanks @dfsq, I actually just did the same thing in a fiddle and came to same conclusion :( So I'm stubbing all over the place now trying to figure out why. – mtpultz Feb 11 '17 at 00:27
  • @dfsq seems the issue is somehow related to another config I've posted above. So I'm trying to find out why now so I can fix it. – mtpultz Feb 11 '17 at 01:29
  • 1
    This can be caused by improper config order, in theory. Why not use `.decorator(...)` instead of clumsy `.config`? It will likely be safer in terms of race conditions.The second snippet is just some random piece of code, I don't see how it is relevant here. But if you don't get decorated `$log` in these services, it makes perfect sense. You're calling `$get()` directly, which is absolute no-no and breaks everything (unless you know what you're doing really well). – Estus Flask Feb 11 '17 at 11:24
  • Oh interesting. Why is $get() a no-no @estus? I ended up making the table `.config` into a `.run` and now it works, but I'd like to know more about `$get()` not being used directly. – mtpultz Feb 13 '17 at 07:58
  • `$get` is internal. Angular services are singletons, but manual `$get` call creates a separate service instance that is not shared with app injector. Moreover, if `$get` has dependencies, they should be passed as arguments manually. It's like having a separate injector with `angular.injector` (not very good thing in most cases too), but in lame way. Usually doing this in `config` indicates XY problem that was solved the wrong way (there are some exceptions where this can be justified). So moving it to `run` was the right move. – Estus Flask Feb 13 '17 at 08:43

0 Answers0