pkaminski / digest-hud

Digest performance analysis HUD for AngularJS.
MIT License
111 stars 20 forks source link

Problems using $filter in templates #9

Closed calamarico closed 7 years ago

calamarico commented 9 years ago

I have detected problems during digest-hud watching expressions when the app uses filters in template, for example: if you have in template:

data-title="'library.nav.allGenres' | i18next"

and if you have enabled digest-hud, the app catch filter error like:

Error: [$injector:unpr] Unknown provider: i18nextFilterProvider <- i18nextFilter http://errors.angularjs.org/1.3.17/$injector/unpr?p0=i18nextFilterProvider%20%3C-NaN18nextFilter at REGEX_STRING_REGEXP (http://localhost:8000/libs/bower-components/angular/angular.js:63:12) at http://localhost:8000/libs/bower-components/angular/angular.js:4031:19 at Object.getService as get at http://localhost:8000/libs/bower-components/angular/angular.js:4036:45 at Object.getService as get at $get as $filter at Parser.filter (http://localhost:8000/libs/bower-components/angular/angular.js:12242:19) at Parser.filterChain (http://localhost:8000/libs/bower-components/angular/angular.js:12236:19) at Parser.statements (http://localhost:8000/libs/bower-components/angular/angular.js:12215:30) at Parser.parse (http://localhost:8000/libs/bower-components/angular/angular.js:12072:22)(anonymous function) @ angular.js:11707$get @ angular.js:8628invokeLinkFn @ angular.js:8292nodeLinkFn @ angular.js:7800compositeLinkFn @ angular.js:7149publicLinkFn @ angular.js:7028$get.boundTranscludeFn @ angular.js:7167controllersBoundTransclude @ angular.js:7827ngIfWatchAction @ angular.js:22205instrumentedListener @ digest-hud.js:405$get.Scope.$digest @ angular.js:14397instrumentedDigest @ digest-hud.js:208$digest @ inspector.js:112$get.Scope.$apply @ angular.js:14660done @ angular.js:9734callbackDecorator @ uniapi.js:7058completeRequest @ angular.js:9924requestLoaded @ angular.js:9865

I think when $parse changes watchExpression, maybe there is a problem, i'm debugging it and i will have more details soon.

pkaminski commented 9 years ago

Thanks for the report @calamarico, these issues can be hard to debug but I hope you find some more details soon. It definitely doesn't affect all filters, since I use a bunch (both standard and custom) in my app without issues. Must be something unusual going on.

calamarico commented 9 years ago

Yeah @pkaminski it's very hard to debug, i see when in instrumentedWatch enters a expression string like "'library.nav.allGenres' | i18next" after Angular throws the exception error trying to find the filter, no filters can invoke in my app if digest-hud is enabled, probably i have a digest collision with 2 or more third party libraries on my app, i continue debugging and trying to see the error, i hope see the light today :D, i want to use digest-hud in my app because it's nice! :D

calamarico commented 9 years ago

One question, i'm using angular 1.3.17, what version of angular do you use?

pkaminski commented 9 years ago

I'm currently on the 1.4.x stream, so it's possible that there's some subtle difference in the internals between the two versions. I was on 1.3.x for a long time while using digest-hud, though, and didn't have any trouble with filters, so it would probably have to be a recent change.

On Thu, Jul 30, 2015 at 12:30 AM, Daniel notifications@github.com wrote:

One question, i'm using angular 1.3.17, what version of angular do you use?

— Reply to this email directly or view it on GitHub https://github.com/pkaminski/digest-hud/issues/9#issuecomment-126209178.

Piotr Kaminski piotr@ideanest.com "That bun is dirty. Don't eat that bun."

calamarico commented 9 years ago

ok man, i'm going to test previous versions of digest-hub

pkaminski commented 9 years ago

I meant recent changes in Angular 1.3.x... digest-hud hasn't had changes to the core code since March, and I was definitely still on 1.3.x back then.

On Thu, Jul 30, 2015 at 12:58 AM, Daniel notifications@github.com wrote:

ok man, i'm going to test previous versions of digest-hub

— Reply to this email directly or view it on GitHub https://github.com/pkaminski/digest-hud/issues/9#issuecomment-126215208.

Piotr Kaminski piotr@ideanest.com "That bun is dirty. Don't eat that bun."

calamarico commented 9 years ago

ok, so i'm going to check since 1.3.1 angular version

pkaminski commented 9 years ago

Hmm, looking at the commit logs I only upgraded to 1.4.x on June 28th, so I must've been on 1.3.16 before then. I don't see anything obvious in the 1.3.17 change log to indicate a change in digest internals... Are you loading any other modules that monkeypatch Angular, by any chance?

On Thu, Jul 30, 2015 at 1:05 AM, Daniel notifications@github.com wrote:

ok, so i'm going to check since 1.3.1 angular version

— Reply to this email directly or view it on GitHub https://github.com/pkaminski/digest-hud/issues/9#issuecomment-126216940.

Piotr Kaminski piotr@ideanest.com "That bun is dirty. Don't eat that bun."

calamarico commented 9 years ago

I have tested since 1.3.1 and they don't work as 1.3.17. I have others modules like ng-i18next or ngInfiniteScroll but it shouldn't applies any patch on Angular, but i have another library that uses $decorator and maybe produces any bad behaviour, i'm checking it

calamarico commented 9 years ago

This is fuc&%$ hard :D i have discard the possible problem with the use of $decorator in other library, but, take a look at this gist: https://gist.github.com/calamarico/fe228afbed495680fa97 The problem is when instrumentedWatch function overrides the prototype of $delegate, if i comment this line: proto.$watch = instrumentedWatch; Injectors are invoked well, but the timing is not working of course hehe.

Well, in the gist, i call directly the native $watch function, this should be work as well right?, yes it works, and of course injectors are invoked well, but i have this error in console: TypeError: deregisterWatch is not a function at Object.fn (angular-animate.js:500) at Scope.$get.Scope.$digest (angular.js:14397) at Scope.instrumentedDigest as $digest at Scope.$get.Scope.$apply (angular.js:14660) at done (angular.js:9734) at callbackDecorator (uniapi.js:7058) at completeRequest (angular.js:9924) at XMLHttpRequest.requestLoaded (angular.js:9865)

angular-animate can't find deregisterWatch, maybe the collision is produced by angular-animate?, this error means anything to you?

calamarico commented 9 years ago

nop i have deleted de angular-animate dependency and still happens :(

pkaminski commented 9 years ago

Yeah, I was tearing my hair out a lot while developing digest-hud. If you can put together a repro for me I'd be willing to take a look at the problem...

On Thu, Jul 30, 2015 at 5:32 AM, Daniel notifications@github.com wrote:

nop i have deleted de angular-animate dependency and still happens :(

— Reply to this email directly or view it on GitHub https://github.com/pkaminski/digest-hud/issues/9#issuecomment-126307414.

Piotr Kaminski piotr@ideanest.com "That bun is dirty. Don't eat that bun."

pkaminski commented 9 years ago

BTW, the deregisterWatch is not a function error is because in your gist your forgot to return the value of originalWatch.call, which is the "unwatch" function.

New guess: since the instrumented watch forces the filtered expression to be parsed earlier than usual, is it possible that the dependency on your filter library isn't loaded yet? Can you add it as a dependency to your top-level app module and see if that helps?

On Thu, Jul 30, 2015 at 5:22 AM, Daniel notifications@github.com wrote:

This is fuc&%$ hard :D i have discard the possible problem with the use of $decorator in other library, but, take a look at this gist: https://gist.github.com/calamarico/fe228afbed495680fa97 The problem is when instrumentedWatch function overrides the prototype of $delegate, if i comment this line: proto.$watch = instrumentedWatch; Injectors are invoked well, but the timing is not working of course hehe.

Well, in the gist, i call directly the native $watch function, this should be work as well right?, yes it works, and of course injectors are invoked well, but i have this error in console: TypeError: deregisterWatch is not a function at Object.fn (angular-animate.js:500) at Scope.$get.Scope.$digest (angular.js:14397) at Scope.instrumentedDigest as $digest at Scope.$get.Scope.$apply (angular.js:14660) at done (angular.js:9734) at callbackDecorator (uniapi.js:7058) at completeRequest (angular.js:9924) at XMLHttpRequest.requestLoaded (angular.js:9865)

angular-animate can't find deregisterWatch, maybe the collision is produced by angular-animate?, this error means anything to you?

— Reply to this email directly or view it on GitHub https://github.com/pkaminski/digest-hud/issues/9#issuecomment-126305281.

Piotr Kaminski piotr@ideanest.com "That bun is dirty. Don't eat that bun."

calamarico commented 9 years ago

sorry for the delay, i was busy with another thing. In the project i have the problem is a business project so i can't share, but in this weekend i will try to reproduce it (copying the dependencies) to a personal project to share with you. In response to your guess, all the third party dependencies are loaded in the top-level module, so i think they sholud be instantiated, but i'm going to think about this idea.

bcoughlan commented 7 years ago

The issue seems to be with $parse reference retrieved here:

if (!$parse) angular.injector(['ng']).invoke(['$parse', function(parse) {$parse = parse;}]);

I don't fully understand the 'ng' parameter to the injector, but for some reason the $parse returned here doesn't pick up my app's filters. Perhaps something to do with using angular.boostrap instead of ng-app? I instead got the $parse from the decorator and it works:

    $provide.decorator('$parse', ['$delegate', function($delegate) {
      $parse = $delegate;
      ...
    }]);
pkaminski commented 7 years ago

I no longer remember why I used angular.injector instead of decorator there... But my app also uses angular.bootstrap so that can't be the sole difference, at least.

In any case, I'm migrating away from Angular and no longer actively maintaining digest-hud. I'm happy to take PRs or hand over maintainer rights to somebody else who's interested, though!