0

I'm currently facing a nightmare in my application. I have 1 Service and 1 Factory and they need to access each other, like so:

// Dependency Injection   
MyFactory(MyService)
MyService(MyFactory)

and this is making my app break (but without errors on console). I have no idea whats going on and I need then to communicate with each other.

Anyone?

Rafael Fragoso
  • 1,299
  • 1
  • 13
  • 21
  • As i remember cyclic dependencies are not allowed in angularjs 1, it throws an error on it. Some time ago i has the same issue, and resolved it by splitting my services to some more little parts – Ильяс Гарифуллин Jan 29 '16 at 12:35
  • 2
    There is a [good question](http://stackoverflow.com/questions/19344214/problems-with-circular-dependency-and-oop-in-angularjs) about this topic, – troig Jan 29 '16 at 12:37
  • 3
    Have you tried creating a 3rd service/factory? This is an interesting read about circular depencencies http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/ – Martijn Welker Jan 29 '16 at 12:37

3 Answers3

3

You created circular-dependency which is wrong.

I found an article from Miško the authors of AngularJS about this problem.

in order to solve this u can use a third service which can use as mediator

ofir fridman
  • 2,691
  • 2
  • 17
  • 27
1

Recursive algorithms aside (I assume you're not dealing with recursion here), you can't have circular dependencies, and that's not an angular restriction.

Without seeing the code, I'd say you have a couple of options

1) Repeat functionality from one in the other so they no longer depend on each other.

2) Combine the two services (may not be possible or appropriate)

3) Split functionality out into more services/factories to break the circular dependency.

Neil Atkinson
  • 724
  • 6
  • 10
0

It's often said that cyclic dependencies is a problem of design and it's true, but sometimes it's just simplier to deal with it. However some case make you have one specially if you don't have control over it.

I had once a circular dependecy : this was because of a configuration on $http interceptor which redirect toward login page using $state of ui-router. And ui-router has a dependency towards $http.

So if you're sure about what you're doing there is a couple of way

1- In myService constructor, call myFactory.setMyService(this).

2- Do a getter function in myService that will look for a field myFactoryif it's initialized. If not call $injector.get("myFactory");

3- For each function that need the cyclic dependcy : use an internal function defined like this :

this.toto = function(params){$injector.invoke(this.totoInternal, this, {params:params}};
this.totoInternal = ['params', 'myFactory' function(params, myFactory){...}]

4- In module.run function instantiate both service (without their dependcies) and set for each of them a field :

module.run(myService, myFactory){
    myService.setMyFactory(myFactory);
    myFactory.setMyService(myService);
}

Point 1 & 2 must be only done in one of them. Point 3 has to be used in both/ Point 4 is setting dependecies before you'll need the actual service (hoping you don't need them in a module.run that would run before.

EDIT : about the 3rd party service that is used as mediator in the accepted answer -> i prefer using $injector as mediator. It's fair enough.

Walfrat
  • 5,363
  • 1
  • 16
  • 35