Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS circular dependency

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 :-)

like image 494
ImSoNuts Avatar asked Apr 07 '14 09:04

ImSoNuts


People also ask

What is circular dependency in angular?

A cyclic dependency exists when a dependency of a service directly or indirectly depends on the service itself. For example, if UserService depends on EmployeeService , which also depends on UserService . Angular will have to instantiate EmployeeService to create UserService , which depends on UserService , itself.

How do you fix a circular dependency problem?

There are a couple of options to get rid of circular dependencies. For a longer chain, A -> B -> C -> D -> A , if one of the references is removed (for instance, the D -> A reference), the cyclic reference pattern is broken, as well. For simpler patterns, such as A -> B -> A , refactoring may be necessary.

What is circular dependency in JS?

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers. While circular dependencies should be avoided where possible, you can't always do so.

Should I avoid circular dependency?

Ideally, circular dependencies should be avoided, but in cases where that's not possible, Nest provides a way to work around them. A forward reference allows Nest to reference classes that have not yet been defined by using the forwardRef() utility function.


1 Answers

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.

like image 117
gkalpak Avatar answered Oct 10 '22 15:10

gkalpak