4

Using AngularFire, I am extending the object factories in order to have encapsulated data and to allow specific features, as explained in the official tutorial. I have a data structure like the following:

{
    'articles': {
        'article-asd876a': {
            title: 'abc',
            text: 'lorem ipsum ...',
            comments: {
                'comment-ad4e6a': true,
                'comment-dsd9a7': true
            }
        }
    },
    'comments': {
        'comment-ad4e6a': {
            text: 'comment text1',
            articleId: 'article-asd876a'
        },
        'comment-dsd9a7': {
            text: 'comment text2',
            articleId: 'article-asd876a'
        }
    }
}

Now I would love to be able to do this:

var article = new Article(8); // Returns the object created by my object factory, fetching data from firebase
var comments = article.getComments(); // Returns an array of type Comment
var firstText = comments[0].getText();
var article2 = comments[0].getArticle(); // article2 === article

But this fails for me on many levels. One of them being: In Article, I can only store the Comment ID, and therefore have to recreate the Comment Object using new Comment(commentId), for which I need to inject Comment into Article. The same is true for Comment, so that I end up with a circular dependency Article -> Comment -> Article. The following fiddle shows the behavior: http://jsfiddle.net/michaschwab/v0qzdgtq/.

What am I doing wrong? Is this a bad concept/structure for angular? Thanks!!

Micha Schwab
  • 786
  • 1
  • 6
  • 21
  • There is no code here using $extendFactory, nor an error that you receive, nor any explanation of what's wrong with having a circular reference in this case. – Kato Oct 08 '14 at 22:39
  • Sorry, I can see this being confusing. I added a jsfiddle showing what I'm trying to do, but I'm still trying to get it to run on jsfiddle. Hope it helps, and thank you for trying. The problem I have is simply that angularjs won't run, only giving me the "Circular Dependency" error. I can do var Comment = $injector.get('Comment'); to avoid the error, is that the best solution? – Micha Schwab Oct 08 '14 at 23:24
  • This has to do with http://stackoverflow.com/questions/19344214/problems-with-circular-dependency-and-oop-in-angularjs, but I don't know what the best solution is when trying to create a relational db abstraction layer. – Micha Schwab Oct 08 '14 at 23:34
  • AngularFire is currently on version 0.8.3 and this fiddle is running 0.3.0. You won't be able to apply any of the principles from the current docs to such an old version. – Kato Oct 09 '14 at 04:15
  • Ok, I edited the fiddle to reproduce the behavior. http://jsfiddle.net/michaschwab/v0qzdgtq/ – Micha Schwab Oct 09 '14 at 21:01

1 Answers1

0

What am I doing wrong? Is this a bad concept/structure for angular? Thanks!!

You are creating circular dependencies.

I can do var Comment = $injector.get('Comment'); to avoid the error, is that the best solution?

I see two solutions:-

1) Lazy injecting solution (you suggested yourself)

This is the best solution to avoid those circular dependencies in AngularJS. Although looking at the AngularFire documentation you are into an uncharted territory as some of these things in AngularFire are experimental in nature.

Here is the working fiddle from your

var Comment = $injector.get('Comment');

You are essentially lazy injecting your references.

http://jsfiddle.net/yogeshgadge/ymxkt6up/5/

2) Module Run block:

With this option you may be able to inject those dependencies into your factories instead of using $injector.

bhantol
  • 9,368
  • 7
  • 44
  • 81
  • Thanks for your suggestions. What I don't understand is why me trying to create a simple relational database leads to me having to enter "uncharted territory" and having to use experimental features. What do all the AngularFire users do, do they just allow writing whatever data properties the controller wants to write? 2) I looked up module run blocks, but haven't yet understood how that can help me - any advice? And why do you think the lazy injections are better? From what I've seen module run blocks are supposed to not be run for the tests, but I think I need the deps to run model tests. – Micha Schwab Oct 15 '14 at 19:26
  • You are essentially trying to create a bi-directional association relationship or a rather composition relationship in Javascript. IMHO ORM is a pain that was tackled by heavy weights like (n)Hibernate etc and the JPA in the Java World. You are trying to represent that relationship in Javascript. Angular promises DI in that it lets you inject objects which are constructors in case of Firebase/your example. I know know any DI implementation that addresses circular dependency problem. So representing a "simple relational relationship" in OO world sans any tools is a stretch. – bhantol Oct 15 '14 at 20:17
  • Run block: I think this will not cut for you now that I understand your question but it is a similar solution only that we remove those dependencies on the factories and at later point i.e. in run() you do the wiring i.e. set the constructor functions so that Comments have access to Article constructor and Article factory will be set with Comment constructor. Lazy $injector is better because it keeps this weaving logic right in the context. Imagine a whole bunch of such relationship end up in a run block - not intuitive. – bhantol Oct 15 '14 at 20:23
  • Ok, that's interesting to me. I'm coming more from the Java and C++ world and am not sure how to code in Angular yet. You're saying the ORM concept might not be worth going for in this environment? If so, what else do you do? Do you not limit how the controllers can interact with the data in any way? – Micha Schwab Oct 15 '14 at 20:23
  • I don;t mean to read into your code but Article has Comments. Article is Aggregate root Entity. – bhantol Oct 15 '14 at 20:25
  • Is that to say that I should leave my code as it is, but to take out Comment.getArticle()? – Micha Schwab Oct 15 '14 at 20:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/63132/discussion-between-bhantol-and-micha-schwab). – bhantol Oct 15 '14 at 20:32