Angular.js: Illegal Invocation Error on Chrome 43.x and angular.js >= 1.3

Created on 2 Jun 2015  路  14Comments  路  Source: angular/angular.js

There is an issue with angular trying to call console.log.

TypeError: Illegal invocation
    at equals (angular.js:1034)
    at equals (angular.js:1034)
    at equals (angular.js:1034)
    at equals (angular.js:1034)
    at equals (angular.js:1034)
    at Scope.$get.Scope.$digest (angular.js:15550)
    at Scope.$get.Scope.$apply (angular.js:15824)
    at tick (angular.js:10983)

I've drilled it down to line 12221 which is:
return logFn.apply(console, args); in consoleLog function.

Seems like Chrome does not allow calling apply on the console object.

Chromium bug report.
Webkit bug report.

More info with my original question is here:
http://stackoverflow.com/questions/30578722/typeerror-illegal-invocation-when-trying-to-upgrade-from-v1-2

chrome

Most helpful comment

Oddly I solved a similar error by prefixing my property with a dollar sign. I was trying to use a directive to populate a scope variable's property for use outside of the directive. I was originally using '_file' and got this error (and googled my way to here). Changing it to $file meant it worked for my purposes. I took the guess on the basis that angular doesn't copy internal variables around.

// Previously
$scope.bob._file = file_object; // From HtmlInput

// Changed to
$scope.bob.$file = file_object; 

I had to use a deep watched isolated scope variable in the directive. There seems to be a number of different use cases above and mine isn't particular similar to any but I thought this may be of use to others.

All 14 comments

Using Chrome 43.0.2357.81 OS X 10.10. The following works from the console

(function() {
  "use strict";
  console.log.apply(console, ['hello']);
}())

Also tried many of the variations and all work.

The bug that you point to talks about console.log not being bound to console, but that is not an issue with the code (and in fact, the bug report is quite old)

Do you have anything installed that would fiddle with console ?

I am having this same issue on OSX 10.9 but not on OSX 10.10.
In my case the problem arises from angular.copy(angularFireObject).
angular.fromJson(angular.toJson(angularFireObject)) works fine, as does angular.copy(angular.fromJson(angular.toJson(angularFireObject)))!
I hope that helps.

I had a similar issue with the equals function in angular.js.
For me it was due to Chrome 43 changing how VTTCue works. Copies of VTTCue now throw Illegal Invocation errors when accessing attributes:

> var cue = new VTTCue(0, 0, 'test');
undefined
> var cuecopy = angular.copy(cue);
undefined
>聽cue.vertical
""
> cuecopy.vertical
VM707:2 Uncaught TypeError: Illegal invocation
    at <anonymous>:2:8
    at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)(anonymous function) @ VM707:2InjectedScript._evaluateOn @ VM221:895InjectedScript._evaluateAndWrap @ VM221:828InjectedScript.evaluate @ VM221:694

The exact same code works in Chrome 42.

On Chrome 43, the following part in angular.copy(>=1.3.0) seems to be illegal for some prototypes such as SVGMatrix, VTTCue.

Object.create(Object.getPrototypeOf(source))
> var cue = new VTTCue(0, 0, 'test')
undefined
> var cueempty = Object.create(Object.getPrototypeOf(cue))
undefined
> cueempty.vertical
VM3268:2 Uncaught TypeError: Illegal invocation
    at <anonymous>:2:8
    at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)
> var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
undefined
> var ctm = svg.getCTM();
undefined
> var ctm2 = Object.create(Object.getPrototypeOf(ctm))
undefined
> ctm2.a
VM3024:2 Uncaught TypeError: Illegal invocation
    at <anonymous>:2:5
    at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)

I think there is nothing actionable here. copy and equals should not have any special logic to handle any of the browser-specific quirks on native objects with js wraps

i get that this seems not the be angular's responsibility, however my apps don't work any more and I need a solution because my clients are unhappy. So let's fix this.
After trying my application in firefox, a different error message I got there led me to this bug: https://github.com/angular/angular.js/issues/11665
Following the advice there (replacing the foreach as suggested by herrevilkitten) fixed the problem for me in chrome too. seems like that should be put into angular.

when i read #8353, which more similar problem to me.
i got this error when try to attach non-angular object to scope.
removing that line, remove my issue as well.
The issue still hit me using Chrome Version 50.0.2645.4 dev-m (64-bit)
Can someone explain clearly, what things possible make this happen?
same TypeError, differenct cause, solved
same TypeError, console related, solved
same TypeError, detail explained, solved

@brutalcrozt, it's not possible to say what's wrong (or how to fix it), without a reproduction.
Please post a live demo of the problem (e.g. using CodePen, Plnkr etc).

@gkalpak

me : removing that line, remove my issue as well.

Thanks for asking, i just wondering when open issue just lead to no where.
i try link some resource that maybe help who got this issue, and i hope folk who got this before me.
So the issue can be solve or close or the team can deal with it. :smile:

Oddly I solved a similar error by prefixing my property with a dollar sign. I was trying to use a directive to populate a scope variable's property for use outside of the directive. I was originally using '_file' and got this error (and googled my way to here). Changing it to $file meant it worked for my purposes. I took the guess on the basis that angular doesn't copy internal variables around.

// Previously
$scope.bob._file = file_object; // From HtmlInput

// Changed to
$scope.bob.$file = file_object; 

I had to use a deep watched isolated scope variable in the directive. There seems to be a number of different use cases above and mine isn't particular similar to any but I thought this may be of use to others.

I'm upgrading to angular 1.3.20. I spot exactly the same problem. I have a directive that allows user to upload images. The Illegal Invocation Error is thrown when I try to add File object to the collection:

       inputElement.addEventListener("change", inputDidChange);

        function inputDidChange() {
          scope.$apply(function () {
            var files, file;

            files = inputElement.files;

            for (var i = 0, l = files.length; i < l; i++) {
              file = files[i];

              if (file.type === "image/jpeg") {
                scope.uploadedImages.push({
                  file: file,
                  didFinish: false,
                  didUpload: false
                });
              }
            }
          });
        }

The error is thrown from angular equals method from this line:

if (!equals(o1[key], o2[key])) return false;

In Firefox different error is thrown:

TypeError: 'name' getter called on an object that does not implement interface File.

Sure enough, changing these lines in my code helps with this issue:

scope.uploadedImages.push({
   $file: file,
   didFinish: false,
   didUpload: false
 });

because Angular will not try to compare file any more:

if (key.charAt(0) === '$' || isFunction(o1[key])) continue;

Closing as the original issues seems to be invalid (or fixed by browsers).

Subsequent comments about calling angular.copy/angular.equals with special objects (e.g. File) are not related to the reported issue (although the error message are similar). The problem with File is tracked elsewhere (e.g. #8312).

Thank you @Olgagr.

I had the same error, when I was deep watching $http.pendingRequests and uploading files with ng-file-upload. Changing the watch to $http.pendingRequest.length solved it.
The idea from @Olgagr brought me to this!

Was this page helpful?
0 / 5 - 0 ratings