1

I have a controller and a factory. A function(myfunc) inside the factory(searchFactory) is called by ng-click of a button. after which I call a function(waitfunction) which is outside the conntroller. In that function timeout of 2 sec is used and then a value is changed and returned to the controller. How can I make sure that the value is updated in the controller after 2 sec. JSfiddle : http://jsfiddle.net/zohairzohair4/cRr9K/1334/

var search_name  
var angularjsapp = angular.module('graphApp', ['ngAnimate', 'ui.bootstrap']);

angularjsapp.factory('searchFactory', function() {
  //return $resource('friends.json');
  return{
        myfunc:function(search_name){
            console.log('ok')
            keyword_type = 1
            loading_value = waitfunction(search_name)
            console.log(loading_value)
            return loading_value
            }
        }   
});

angularjsapp.controller('AccordionDemoCtrl', function($scope,searchFactory) {
    $scope.count = 0;
    $scope.namesPerPage = 10
    $scope.currentPage = 1;
    $scope.searchFactory = searchFactory.myfunc 
});

function waitfunction(search_name){
            value = 0
            window.setTimeout(function () {
                        value = 1;
                    }, 2000);
            return value        
        };
Zohair Zahid
  • 119
  • 2
  • 15
  • Sounds like a dup of this one http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – elclanrs Jun 29 '16 at 12:13

2 Answers2

2

Using the setTimeout function will bypass angular's dirty checking. If you want to use async functionality outside of angulars dirty-checking, you need to trigger angular to do the dirty checking again. You can do that by calling $scope.$apply(); or wrap your async call with a function like this:

$scope.$apply(function() {
...
});

For your specific need - angular already have a number of async methods to replace the default javascript ones and i'd suggest you use that instead of javascripts timeout:

$timeout(function () {
  value = 1; 
}, 2000);

You can read more about $timeout here: https://docs.angularjs.org/api/ng/service/$timeout

Your waitfunction doesn't seem to be doing what you want it to do. It will return the value long before the timeout changes it. This happens because you're just referencing a simple value. If you pass an object and modify that objects property, then you can achieve what you're trying to do:

function waitfunction(search_name){
    var obj = { value: 0 };
    $timeout(function () {
      obj.value = 1;
    }, 2000);
    return obj;       
};

You then need to bind to the returning objects .value property instead.

I see your plunker and there is a lot of work to be done. It doesn't seem like you're binding the resulting object to anything. I think this post helps to solve atleast the async problem associated with calling setTimeout and the problem of binding to simple values.

Per Hornshøj-Schierbeck
  • 15,097
  • 21
  • 80
  • 101
  • Error: $scope is not defined – Zohair Zahid Jun 29 '16 at 13:21
  • @ZohairZahid there is so much work to be done in your example, I don't know where to start. You don't need to wrap a call to $timeout in $scope.$apply. The reason your $scope is undefined is because it's not in your controller. You are not using the value from the wait anywhere. I see lots of code not doing anything and lots of stuff not hooked up... – Per Hornshøj-Schierbeck Jun 29 '16 at 13:39
0

You need to use $timeout

$timeout(function() {
                value=1;
            }, 2000);
Per Hornshøj-Schierbeck
  • 15,097
  • 21
  • 80
  • 101
zeeshan Qurban
  • 387
  • 1
  • 3
  • 15