-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Injector incorrectly infers injectables for ES6 classes #14789
Comments
Looks like the issue does not occur in Firefox.
prints
|
@petebacondarwin could you TAL? @TEHEK also has an idea on how to fix, maybe share it here? |
Sure. In ES6 class declaration constructor is a method declaration within the top
It can assume the input syntax is valid since browser takes care of that. |
That doesn't matter. If the fn.toString() returns something that starts with "class ... { ... }", it could be parsed. Firefox returns the constructor function declaration, so the old injector works just fine. |
But once they sort themselves out, then some micro-parser would be great. |
... unless Chrome behavior is going to change to match others in which case it would be just a wasted effort :) |
This is essentially a known issue (e.g. see #14175 (comment)).
I think we should just document it as a known issue for now. BTW, Firefox's behavior is violating the spec and causing another bug (when trying to determine whether to pre-assign bindings on a directive controller). |
Where should this be documented? |
Given that there is a very reasonable workaround (to annotate the class), which is actually what you would expect to do in production anyway, then I am happy to go with the documentation option for now. @TEHEK would you like to comment? |
Well, i guess documenting the caveat is reasonable. The magic auto-injection is what makes angular so attractive in the first place. I'll keep the microparser in my backlog just in case. |
@TEHEK - thanks. Perhaps an alternative place to look to add this micro-parser is the ng-annotate project? |
Sorry, didn't mean to close this until we have the documentation sorted. |
Magic auto-injection is a bad feature that should never have been there in the first place. In what other context does the name of a parameter influence anything. Angular's magic DI system uses the name to infer the type, but one should be able to call a parameter anything they would like. When I started using angular, over 3 years ago, I was very confused by this behavior. At the time I didn't know how angular knew what to inject. I did some research and found out it was using That was a long time ago and much has changed for the better. The docs use better examples, mostly, and a number of well reasoned patterns and practices have become mainstream thanks to people like @johnpapa. I think it's time to deprecate this feature. |
Injection mechanism is already different in Angular2. Ditching existing users by deprecating a core feature is a no-go, imo. Users have a reasonable expectation that injector should just work when, for example, they migrate to ES6 classes. Yes injection magic is not ideal, but at least it was consistent. |
I am saying that it should be deprecated in the next version. If you want to deploy your app, you have to rewrite you code or run it through a tool. |
Unless the feature is going away, there's no point in adding a useless deprecation warning. And i think removing auto-injection is a major breaking change not suitable for 1.x branch. |
It is not productive to have this conversation in two places. Let's continue in #14175. |
Let's close as a duplicate then |
TL;DR: Using ES6 classes and Angular has a huge caveat. A temp workaround is to:
extractArgs
method relies on a regular expression to extract function arguments. However when instantiating an ES6 class, the regexp may fail. E.g.:https://jsfiddle.net/ykmtej1j/
vs
https://jsfiddle.net/ykmtej1j/1/
In the first example the
extractArgs
incorrectly infersmethod(wrongArgument)
as constructor (it's only looking for opening parenths).Regular expression is not safe to use with ES6 classes. And unless there's a way to extract the constructor method at runtime,
extractArgs
would need a real JS AST parser to correctly and reliably infer constructor arguments.The text was updated successfully, but these errors were encountered: