Rouz
Rouz

Reputation: 1367

$watch vs curly braces - $watch does not catch change of a variable on scope

I have a problem in AngularJS. I will try to simplify things to explain the problem I am having.

I have created a directive that should handle image uploading. The flow goes like this.

If the image exists server will return the url of a statically served image. The url and the directive are loaded asynchronously from server so there is no way of telling which one will load first. I pass a variable that I get as an attribute

<my-directive vc-current-url="vm.data.profileURL"> </my-directive>

Directive scope

scope : { "currentURL" : '=vcCurrentUrl' }

So, in my template I am able to {{scope.currentURL}} and when it gets loaded - it will show up. But I have to do more things when that url is loaded - pass it to another function (reasons). So fine I will just add a watcher and wait for it to load? But not.

scope.$watch(scope.currentURL, function (newValue, oldValue) {
    console.log(' changed to ' + newValue + ' from ' + oldValue);
}, true);

console.log gets called once and it prints

changed to undefined from undefined

What am I missing?

Oh and I'm using Angular 1.5.

EDIT Couple of answers were that I did not watch the correct variable. The code below does not work and it throws

Error: currentURL is not defined

Code:

scope.$watch('currentURL', function (newValue, oldValue) {
    console.log(' changed to ' + newValue + ' from ' + oldValue);
});

Upvotes: 1

Views: 84

Answers (3)

Rouz
Rouz

Reputation: 1367

So I was wrong.

Austn and Alon were right but I failed to notice that they had apostrophes around the variable name and I do not have them.

Following the conversation I tried to put my watcher function in $timeout. The variable loaded in next cycle and I got some weird parse message (that url.com/variable.jpg is not a valid var name).

So at that point I realized that if you don't put var name inside apostrophes it will use the var value (or undefined).

So why did I get that console log and what I did was actually

$watch(undefined, function() {...}); 

and watcher is usually called once on initialization. Thank you all for help.

Upvotes: 1

Austin
Austin

Reputation: 1291

Try this instead:

scope.$watch('currentURL', function (newValue, oldValue) {
    console.log(' changed to ' + newValue + ' from ' + oldValue);
});

You were not referencing the scope variable correctly.

Upvotes: 1

Alon Eitan
Alon Eitan

Reputation: 12025

First, this is how you watch the value

scope.$watch('currentURL'

Second, this is how you're scope def looks like

scope : { "currentURL" : '=vcCurrentUrl' }

So your directive on the view should be

<my-directive data-vc-current-url="vm.data.profileURL"> </my-directive>

Upvotes: 1

Related Questions