0

fiddle: https://jsfiddle.net/ahmadabdul3/L3eeeh6n/

I'm building an app. This app starts with some static data that I can add to, remove from. The problem I'm having (circular dependency) comes from this initial static data. Here's the scenario:

I have 2 services (fruit, basket). Each fruit can belong to only 1 basket, but each basket can hold many fruits. These two services (below) depend on each other:

function fruitService() {}
function basketService() {}

the reason they depend on each other is because of the initial static data that I have:

function fruitService(basketService) {
  var data = [
   {
     id: 0,
     name: 'apple',
     basket: function() { return basketService.getById(this.refs.basket); },
     refs: {
       basket: 0
     }
   }
  ];
}

as you can see, I have a function basket that returns a basket item, so that I can dynamically retrieve basket objects from fruit objects.

the basket service is similar:

function basketService(fruitService) {
  var data = [
   {
     id: 0,
     name: 'basket1',
     fruits: function() { return fruitService.getByIdList(this.refs.fruits); },
     refs: {
       fruits: [0, ...]
     }
   }
  ];
}

same as the fruitService, I have a fruits function that can give me fruit objects when I ask for them. I've tried different combinations of ways to try to break apart the actual static data and the service to overcome this circular dependency, but its not happening.

how can I architect this without having this circular dependency

Abdul Ahmad
  • 9,673
  • 16
  • 64
  • 127

3 Answers3

1

Have one of the services use $injector and do a lookup for the service at runtime

var injectedService = $injector.get('servicenamehere');

You will need to add $injector to your service parameters for this to work (just in case there was any question)

Dave Bush
  • 2,382
  • 15
  • 12
1

You don't need 2 services. I think that one is enough.

function basketService() {
  var data = [
   {
     id: 0,
     name: 'apple',
     basketName: 'basket1'
   },
  ];

  var service = {
    getFruitById: getFruitById,
    getBasketById: getBasketById
  };

  function getFruitById(fruitId){
    // return one fruit here
  }

  function getBasketById(basketId){
    // return your basket with a list of fruits
  }
}
Deblaton Jean-Philippe
  • 11,188
  • 3
  • 49
  • 66
  • I'd like to keep the code modular and maintainable. I may not have mentioned this in the question but this app will grow. As the number of functions increases, this file will become really big. And what if I need to add more services in the future. This solves the problem, but is not ideal for maintainability – Abdul Ahmad Feb 04 '16 at 14:38
  • As far as maintainability is concerned, the fact that you have duplicated data in both services is worse than a unique service. I'll update my answer, keeping 2 services and 1 constant. – Deblaton Jean-Philippe Feb 04 '16 at 14:47
  • what do you mean duplicated data? theres no duplicated data – Abdul Ahmad Feb 04 '16 at 14:48
  • @AbdulAhmad sorry I misread. I though your basket contained a list of fruits ID – Deblaton Jean-Philippe Feb 04 '16 at 14:57
  • my basket does contain a list of fruit ids, its like a foreign key in a sql table. this way I don't load an actual fruit if i don't need it, just a reference to it. and if I need it, i just call the "fruits" function and it'll return the fruits that are in the basket. its like a relational database – Abdul Ahmad Feb 04 '16 at 14:58
  • in a relational database, you do not duplicate foreign keys. – Deblaton Jean-Philippe Feb 04 '16 at 15:24
  • where am i duplicating a foreign key? bro are you just here to fight or something? or to prove that you're right? this answer is crap by the way because its hard coding basket names into the data. what if I want to change the basket that the fruit belongs to. think about your answers before posting – Abdul Ahmad Feb 04 '16 at 15:45
0

Another option would be use a constant to store your data.

angular.module('yourApp').Constant("fruitAndBasketConstant", {
    baskets : [{
        id : 0,
        fruits : [
            {
               // some info
            },
            {
               // some info
            }
        ]
     }]
});

And create a service that will query your constant.

angular.module("yourApp").factory("FruitService"["fruitAndBasketConstant", function(fruitAndBasketConstant){

    var service = {
        getFruitById: getFruitById
    };

    return service;


    function getFruitById(fruitId){
        // loop through fruitAndBasketConstant.baskets

        // and return the fruit you want
    }

}]);

And do the same for your basketService.

Deblaton Jean-Philippe
  • 11,188
  • 3
  • 49
  • 66