4

How can I call a function in my controller from inside a $scope.watch function? I try something like this, but that doesn't work

$scope.$watch(function(){return self.user}, function (newVal, oldVal, scope){
if (self.user) {
    getNotificationCount();
  } 
});

var getNotificationCount = function(){
  console.log("called your function");
}

it gives me an error

TypeError: getNotificationCount is not a function
2
  • try moving the function to top, or declare in a scope. Commented Nov 25, 2016 at 6:35
  • your getNotificationCount(); should be like $scope.getNotificationCount(); and your function declartion should be like $scope.getNotificationCount()= Commented Nov 25, 2016 at 6:43

4 Answers 4

1

You need to define getNotificationCount before calling it.

var getNotificationCount = function(){
  console.log("called your function");
}

$scope.$watch(function(){return self.user}, function (newVal, oldVal, scope){
  if (self.user) {
    getNotificationCount();
  } 
});
Sign up to request clarification or add additional context in comments.

1 Comment

or keep getNotificationCount where it was but call function getNotificationCount() { console.log("called your function"); } which hoists getNotificationCount at the top of the code
1

Declare the function within the angular scope :

$scope.getNotificationCount = function(){
  console.log("called your function");
}

2 Comments

Defining function not directly used in model as a scope field is not advised as it leads to scope pollution. One should only make function a scope field if it's used directly in view (eg. in ng-click).
@Michał , you are right.@OP, refactor your code as per your requirement , i.e , use aforementioned code , if it has any reference through the view.
0

Its because of the variable hoisting. when you have a function expression that is declared later in the code, it just hoists the variable declaration and assigns the method to it as per the sequence of execution.

In your case, getNotificationCount variable is declared but it is assigned a function reference later. So, to get around the issue, you either need to move the function expression to a place before you make a call or use function definition like function getNotificationCount(){};

You can read more about function hoisting here

Comments

0
$scope.$watch(function(){return self.user}, function (newVal, oldVal, scope){
  if (self.user) {
   getNotificationCount();
  } 
});

var getNotificationCount = function(){
 console.log("called your function");
}

In the current code snippet the problem lies in the way you are trying to declare a function getNotificationCount, you are declaring a function by assignment. Therefore, execution order sets in a way that first $scope.$watch code block will execute and once it is completed, variable declaration getNotificationCount will execute.

But if you define the you getNotificationCount method as a function expression, then

 function getNotificationCount() { 
   console.log('calling your function') 
 }

you will not get an error. All the function expression in a scope are evaluated before an execution order is set in place. It doesn't matter whether you define a function this way whether before or after $scope.$watch(). So, when you define a method in this manner, compiler will first evaluate all the method definitions, then when the execution order reaches the $scope.$watch statement, it will already have the function definition to getNotificationCount to invoke.

In your case the compiler doesn't even know before hand what exists on the right hand side of the var getNotificationCount until it reaches to execute it after $scope.$watch executes( in case this even completes without throwing an error)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.