$timeout with 0 bad practice?

268 views
Skip to first unread message

Billy Figueroa

unread,
May 1, 2014, 4:04:50 PM5/1/14
to ang...@googlegroups.com
Is is bad practice to use $timeout with a time of 0?

i.e.
$timeout(function() {
   // some action here
}, 0);

I find that sometimes data doesn't load in a child controller and I may want to use this. I have avoided using it, but what are peoples experience with this?


Chris Rhoden

unread,
May 1, 2014, 4:06:43 PM5/1/14
to ang...@googlegroups.com
The 0 isn't necessary, and using $timeout to defer some action isn't an antipattern, but the rest of your message concerns me. If you're communicating between controllers using $scope, you're doing it wrong. Make a service if two controllers need to share state.


--
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.
For more options, visit https://groups.google.com/d/optout.



--
chrisrhoden

Billy Figueroa

unread,
May 1, 2014, 4:13:44 PM5/1/14
to ang...@googlegroups.com
I do have a service. Its called DataFactory.

I just found that you can achieve the same results with out using a factory and calling the factory in each controller.

The way I have my app setup I am getting the current users data in a MainController which I set on the body tag so EVERY single page and controller instantiated with that route will have MainController as a parent.

I could then load the data using $timeout OR as you mentioned just use a service. Using a service means I call my DataFactory in every single controller that I need that data which although it seems like thats the point of services and dependency injection, it causes multiple calls of the same code. Whereas with a simple timeout I can just grab the data that is already there in the parent controller.

I am using the service/ factory method for sure, but I just wanted to know if its bad practice to do it the other way

Jeff Hubbard

unread,
May 1, 2014, 7:31:20 PM5/1/14
to ang...@googlegroups.com
It sounds to me like DataFactory should return a promise instead.

Billy Figueroa

unread,
May 1, 2014, 8:25:35 PM5/1/14
to ang...@googlegroups.com
I am already doing that. We are focusing too much on the factory method. My question is regarding the $timeout method

'use strict';

mintApp.factory('DataFactory', ["$http", function($http) {

    var factory = {};

    factory.getUserData = function() {
        return $http.get('../MINT/scripts/php/get_user_data').then(function(results) {
            if (results.status === 200) {
                return results.data.User;
            } else {
                return {
                    status : results.status,
                    error  : 'Failed to get User Data'
                }
            }
        });
    };

    return factory;
}]);

and then in the controller I use it

 DataFactory.getUserData().then(function(results) {
     $scope.account = results;
 });

Sander Elias

unread,
May 2, 2014, 2:25:21 AM5/2/14
to ang...@googlegroups.com
Billy,

You need to take a look at resolve, and there are some other techniques available too to make this work.
While there is nothing wrong with using $timeout to defer code outside the digest circle, the way you are using it is
plain wrong. 
Let me explain a bit, a async operation like $http does not make any guarantee when it comes back. If you are working locally
on your own machine, it gives fair odds the data will be in in the next digest cycle. However, if it takes only a few milliseconds more to fetch,
 the $timeout will miss it. If you put this in production, it will have a much higher miss rate, as data needs to travel over the network!

I have this sample in where there are multiple ways to work around this. Have a look at it, and if you have questions,
don't hesitate to ask.

Regards
Sander

Marcos Lin

unread,
May 2, 2014, 3:47:31 AM5/2/14
to ang...@googlegroups.com
Your DataFactory looks ok.  Could you elaborate on why "sometimes data doesn't load in a child controller"?  Based on your question, it seems that you are not calling DataFactory in your $timeout.  Given that you are using a "child" controller, perhaps some of the action can be done at the parent controller?

Use of $timeout with 0 is fine as long as you know why it is needed.  If you are doing it just because it works now, it might break after you go prod and you would end up with serious bug.

Billy Figueroa

unread,
May 2, 2014, 10:22:55 AM5/2/14
to ang...@googlegroups.com
Sander thanks for that, I know a little bit about resolve. Your saying I can use resolve and have a function where I make a call to my DataFactory before we go to the route so that I have my data once the view is loaded right?

Just looked at your plunkr, a lot to take in lol I need to go back to it and view it when I have more time.

I like the idea of using resolve. Can you use resolve as well as using a custom controller variable to control member access?

for example, resolving first to grab the data, then also having something like restrict: true

i.e.

when('/whatever', {
   templateUrl: 'someurl',
   controller: 'someController',
   resolve: {
      var data = DataFactory.getData().then(function() {
                         // do some action
                     })
   },
   restrict: true
})

pardon me for not using a plnkr, I am at work and often I just don't have the time to do them. These projects I work on are personal projects, not work projects so I can't do this during work.

Also THANK YOU for the named template idea. I like how you are using a name: variable on each route to be able to use it for example with highlighting the right button for which view you are on. I love that idea. I m going to use it

I am just learning angular so although I know how resolve can work, I haven't developed good habbits yet. This is why I ask so many "is this good/ bad practice" type of questions. Just trying to learn how to do things in angularjs coming from jquery and plain javascript

Marcos,

Thanks for the input, the problem is when using $timeout. That snippet of code I showed you is not using $timeout so that's probably why you don't see anything wrong
Reply all
Reply to author
Forward
0 new messages