AngularJS: $watchCollection does not work; throws error - javascript

I've got a problem in AngularJS where $scope.$watchCollection() throws an error. I've reduced my code to the point where it's exactly the same as example code in the docs (http://docs.angularjs.org/api/ng.$rootScope.Scope#$watchCollection), and the error is still thrown:
function OverviewCtrl($scope) {
$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;
$scope.$watchCollection('names', function(newNames, oldNames) {
$scope.dataCount = newNames.length;
});
}
I get the error
'undefined' is not a function (evaluating '$scope.$watchCollection('names', function(newNames, oldNames) {
$scope.dataCount = newNames.length;
})')
I have no idea what the problem could possibly be. I'm doing exactly what the docs say, except I'm putting it in a controller, but it seems this code is intended for use in controllers. So what's the problem here?

You could also use the following syntax :
$scope.$watch('myCollection', function(value, oldValue) {
// insert awesome code here
}, true);
The true parameter tells AngularJS to "deepwatch" the value.

Related

Cannot set property 'classRules' of undefined

am just don't know what happened it was work correctly .... What's most reasons that led us to this error ????
I was trying to run my website locally then this error comes to me from I don't know so what is this error mean and how can I solve it
the error occurs in this code .... actually , its complete website and I'm a beginner with JS and SO so please help me
// disable class and attribute rules defined by jquery.validate
$.validator.classRules = function() {
return {};
};
$.validator.attributeRules = function() {
return {};
};
Your Code tries to access an non existing JQuery namespace. You are either missing some sort of JQuery plugin, or you need to create on your self.
If you would like to create the validator namespace you can use such sample code as described here
(function ($) {
// do not overwrite the namespace, if it already exists
$.validator= $.validator|| {};
$.validator.classRules = function () { return {};}
$.validator.attributeRules = function () { return {};}
})($);

Angular not working on IE9 possibly due to internal injector?

I have a angular 1.3.15 application which doesn't work on Internet Explorer 9, I get a Unable to get property 'replace' of undefined or null reference error which points to this block of code in the angular core.
The error is thrown that much is executed correctly but I have no ideea what this function normally does and what's missing on IE9 for it to work.
function createInternalInjector(cache, factory) {
function getService(serviceName, caller) {
if (cache.hasOwnProperty(serviceName)) {
if (cache[serviceName] === INSTANTIATING) {
throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
serviceName + ' <- ' + path.join(' <- '));
}
return cache[serviceName];
} else {
try {
path.unshift(serviceName);
cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName, caller);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally {
path.shift();
}
}
}
As a final note I've included es5-shim and shams, I already use data-ng-* attributes I've read multiple articles about getting angular to work on IE9 but none of them describe a problem similar to this one so I'm left with only asking this question on SO.
So I found the issue by adding breakpoints and debugging till I found the name of the service it couldn't inject $location and this stemmed from me trying to use html5 mode:
$locationProvider.html5Mode(true).hashPrefix('!');
If I comment this and use the # routes the application works as far as I can tell, if anyone has a ideea on how to use html5mode in IE9 I'll mark your answer as the correct one as I don't want to answer my own question.

Not getting javascript exception.stack in IE inside of angular controller

I am building an angular web application and I am wanting to send any javascript exceptions and callstacks from the client to the server for logging. In chrome and firefox I am able to get the callstack by looking at the exception.stack property, but this value is not available when using IE. Here is a code example from my angular controller:
function LogTestController($scope) {
$scope.TestError = function () {
callError1();
}
function callError1() {
callError2();
}
function callError2() {
var x = y;
}
};
And here is the exception.stack from chrome:
"ReferenceError: y is not defined
at callError2 (http://localhost:85/App/Offer/OfferController.js:16:17)
at callError1 (http://localhost:85/App/Offer/OfferController.js:12:9)
at Scope.LogTestController.$scope.TestError (http://localhost:85/App/Offer/OfferController.js:8:9)
at $parseFunctionCall (http://localhost:85/Scripts/angular.js:12345:18)
at ngEventDirectives.(anonymous function).compile.element.on.callback (http://localhost:85/Scripts/angular.js:21435:17)
at Scope.$get.Scope.$eval (http://localhost:85/Scripts/angular.js:14401:28)
at Scope.$get.Scope.$apply (http://localhost:85/Scripts/angular.js:14500:23)
at HTMLButtonElement.<anonymous> (http://localhost:85/Scripts/angular.js:21440:23)
at HTMLButtonElement.jQuery.event.dispatch (http://localhost:85/Scripts/jquery-1.9.1.js:3074:9)
at HTMLButtonElement.jQuery.event.add.elemData.handle (http://localhost:85/Scripts/jquery-1.9.1.js:2750:46)"
Which is very helpful in debugging. But IE does not have the extension.stack property when the error occurs inside of the angular controller.
However if I force the same error in IE when it is not inside an angular controller then there is a value for exception.stack. Here is an example of that code:
<script type="text/javascript">
try {
first();
} catch (exception) {
var trace = exception.stack;
};
function first() {
second();
};
function second() {
var x = y;
}
</script>
In IE the exception.trace is as follows:
"ReferenceError: 'y' is undefined
at second (http://localhost:85/App/logtest.html:20:13)
at first (http://localhost:85/App/logtest.html:16:13)
at Global code (http://localhost:85/App/logtest.html:10:13)"
I have also tried to use stacktrace.js to get the callstack from IE, but this library is reliant on the exception.stack value to be present.
Could somebody please help me understand why this is acting differently when inside an angular controller and how to get the stack trace from IE inside the angular controller?
Thanks

Getting a Syntax/Parse error when using jQuery in Velocity

<script type="text/javascript>
(function($, win) {
function mySettingsInitJS () {
var self = this;
var opts = {
'params' : "userId=" + userId;
};
self.init = function() {
self.initUnlinkAction();
};
self.initbtnAction = function() {
$('#Btn').click(self.btnAction);
};
self.btnAction = function(e) {
if(e) { e.preventDefault(); }
jQuery.post(
'http://abc/rest/PostRequest',
opts.params, function(data) {
alert('This worked!');
}, "json");
};
}
function win.MyFilesSettingsInitJS = new MyFilesSettingsInitJS();
}(jQuery, window));
</script>
I have this this script in a velocity template page and a Btn also in it. Which is basically a fancy Link. I am also sure the rest API on the server side is working fine. But somehow my java script function is not called. Could some one please help me ?
Seems like you forgot quotes here:
'http://abc/rest/PostRequest'
It becomes pretty obvious with good syntax highlighting. Plus if you use JSLint or similar it will find most problems, as well as the console when debugging your code.
Your URL value needs to be a string...add quotes to it
You should use some developer tools available in the browser. Most browsers have at least an error console that would display any JS errors. For example, this code has several syntax errors:
In var opts = { 'params' : "userId=" + userId; }; it is illegal to end a line with ; when you're defining an object literal (a.k.a. map or dictionary).
Again at this line, where is userId defined? It is a bad practice to have global variables, so if userId is a global variable defined in another script, you should refactor the code
function win.MyFilesSettingsInitJS = new MyFilesSettingsInitJS(); is illegal, since you're adding a property to an object, you're not declaring a function or a variable. Just use win.MyFilesSettingsInitJS = new MyFilesSettingsInitJS();
Actually, that might be wrong as well, since above you defined mySettingsInitJS, not MyFilesSettingsInitJS (but that function could actually be defined somewhere else, I don't have the whole code)

Having IE Issues When Passing Object By Ref. and Dynamically Adding Properties

So, I've created a function to do some error checking on an XML file that I recieve from an AJAX call. Part of the validation is that the function then builds out an object for easy access while I process that data into a form. In FF, works like a charm. IE dies with the error:
Object doesn't support this property or method
Here is the function (minus the un-important bits):
function checkReceiveXMLTagString( doc, messageObject, tag ) {
var tag_nodes = doc.getElementsByTagName( tag );
...do some error checking...
messageObject[tag] = tag_str; <-- error occurs on this line
return true;
}
Here is an example of how the function is call:
if ( checkReceiveXMLTagString( messageObject.Name[0], messageObject.Name[0], "First" ) ) {
...process messageObject.Name[0].First...
}
Like I said, FF has no issues. Safari loads the pages as well. IE has issues.
Thanks!
Looks like something is making messageObject be null or undefined
If the error is on this line:
messageObject[tag] = tag_str;
Then, the only two ways I know of that that can cause an error are:
messageObject is not an object that you can set properties on (null or undefined are the most likely ways that would happen)
tag is null or undefined
Since I see that your code calls this function hundreds of times so you can't effectively just break on it, I'd suggest you put in some defensive coding to check for those conditions and output something to the debug console to identify what the state is when the problem occurs. You can even trigger a conditional breakpoint with code like this:
if (!messageObject || !tag) {
debugger;
}
In the toughest cases, you can put an exception handler around it and break when the exception is thrown:
try {
messageObject[tag] = tag_str;
} catch(e) {
debugger;
}
Both of these will allow you to capture the condition in the debugger and examine all your parameters at the time of the error.

Categories