The best way of waiting with initialization of nested controllers till parent is fully initialized

4,836 views
Skip to first unread message

Marek Lewandowski

unread,
Mar 10, 2013, 12:12:35 PM3/10/13
to ang...@googlegroups.com
Hello,

Scenario:
- Main Controller fetches data from webservice upon initialization
- nested controller must do something on that data upon its own initialization

I wonder what is the best way of solving that issue?

Here is example of the problem. It fails because data is not available while nested controller is being initialized. Example is very primitive, what's important is that some data is fetched from webservice and assigned to scope. Then nested controller expectes that data but there's nothing and everything fails.


and here is the solution to this problem using $q service 

I tried to use resolve on route but I could not inject $scope so I gave up and tried promises as shown above.

Questions:

1. Is there a better way of doing that?

2. Generally, how initialization should be done? So far I've been writing some code inside controller, followed by methods assigned to scope and I'm not happy with that. It lacks structure. 

Kind regards,
Marek
 

Clint Checketts

unread,
Mar 10, 2013, 1:22:48 PM3/10/13
to ang...@googlegroups.com
Here are 2 approaches I'd look at:

Either a watch on the value in scope, or just  helper function that does the proper traversal. I favor the second approach. Another more complex approach is to broadcast and even and have the child scope watch or the event so it knows to update the $scope.first value. The reason I favor the helper function is that it isn't saving to any separate variable that could get out of sync from the parent object.

//Using a watch
  $scope.$watch('commits[0]',function(){
    if($scope.commits && $scope.commits[0]){
      $scope.first = $scope.commits[0].author;  
    }
  });
  
//Using a helper function
  $scope.getFirst = function(){
    if($scope.commits && $scope.commits[0]){
      return $scope.commits[0].author;  
    }
  };

http://plnkr.co/edit/hlLxvOv9U8nNJ0Q6r5b0?p=preview


 

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Marek Lewandowski

unread,
Mar 10, 2013, 2:28:54 PM3/10/13
to ang...@googlegroups.com
Helper function looks cool, but I guess I might have explained problem the wrong way ( or maybe I think of it the way I should not )

My real use case is that I fetch some Resource in one controller and then depending on some property of that resource I fetch another different resource in nested controller (so second controller needs to wait for first). After that none of the resources are changed. Some of their properties might be updated but there is no need to fetch anything again. If I used $watch then it would trigger only once. Same with broadcasting, which would work too but I'd receive only one event like "resource-ready" or something. 

Given more light on that matter, what would you suggest?

Clint Checketts

unread,
Mar 10, 2013, 2:45:37 PM3/10/13
to ang...@googlegroups.com
Creating a service would be what you'd want. Kind of like the next level after helper functions.

Peter Bacon Darwin

unread,
Mar 10, 2013, 4:40:58 PM3/10/13
to ang...@googlegroups.com
I would go with the $q promises.  This is exactly what they are designed to be used for.
First of all you almost never need to create your own deferred objects.  If you have something that it returning you a promise that will be resolved by someone else then this is all you need.  (Only create a deferrred if there is some other external trigger - other than the original promise being resolved - that will trigger the deferred to be resolved).

Further I would push all of this into a service.

Finally if you are using routes then resolve is a perfect partner for all of this.


 

--

Marek Lewandowski

unread,
Mar 10, 2013, 5:59:34 PM3/10/13
to ang...@googlegroups.com
 That's really elegant approach.  Although in my real case I used $resource and it returns empty object, not a promise so there's some issue with that. Talking about resolve... would you mind creating a plnkr? I've created http://plnkr.co/edit/a8iqWh?p=preview  with routes so if you would be so kind and add resolve that would be great. I've tried it earlier (with my real use case) but quickly failed. It looked like I could not inject $scope to the function but maybe I did something else wrong.

Is creating deferred inside service which uses $resource a right thing to do in this case? or resolve is better? (still don't know how to use it correctly)

Peter Bacon Darwin

unread,
Mar 10, 2013, 6:06:50 PM3/10/13
to ang...@googlegroups.com

Marek Lewandowski

unread,
Mar 10, 2013, 6:35:49 PM3/10/13
to ang...@googlegroups.com
Cool, thanks. I'm guessing that should be preferred approach.
Reply all
Reply to author
Forward
0 new messages