AngularJS circular dependency

ImSoNuts picture ImSoNuts · Apr 7, 2014 · Viewed 21.8k times · Source

I'm making a logger service, to extend angular's $log service, by saving the errors (or debug if enabled) into an indexedDB database. Here's the code:

angular.module('appLogger', ['appDatabase'])

.service('LogServices', function($log, Database) {

    // ...

    this.log = function(type, message, details) {
        var log = {};
        log.type = type
        log.context = this.context;
        log.message = message;
        log.dateTime = moment().format('YYYY-MM-DD HH:mm:ss');
        log.details = details || '';
        $log[type.toLowerCase()](log);

        if (type === 'ERROR' || this.logDebug) {
            Database.logSave(log);
        }
    };

    // ...
})

This is working in my services as intended. Now the problem is I can't use my logger inside the Database service, because it throws a circular dependency error. I understand the problem but I have no clue how should I resolve it... How should I get around this ?

Thanks for helping :-)

Answer

gkalpak picture gkalpak · Apr 7, 2014

The reason Angular is complaining about a circular dependency is that...well there is one.
It is a very dangerous path to go down, but if you know what you are doing (famous last words) then there is a solution to circumvent that:

.service('LogServices', function($log, $injector) {

    // ...

    var Database;   // Will initialize it later

    this.log = function(type, message, details) {
        /* Before using Database for the first time
         * we need to inject it */
        if (!Database) { Database = $injector.get('Database'); }

        var log = {};
        log.type = type
        log.context = this.context;
        log.message = message;
        log.dateTime = moment().format('YYYY-MM-DD HH:mm:ss');
        log.details = details || '';
        $log[type.toLowerCase()](log);

        if (type === 'ERROR' || this.logDebug) {
            Database.logSave(log);
        }
    };

    // ...
})

See, also, this short demo.