angular: AoT "function calls are not supported" error with exported animation function
I’m submitting a … (check one with “x”)
[X] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
Currently I’m getting an error of the form:
ERROR in Error encountered resolving symbol values statically. Calling function 'rotate', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppComponent in /Users/chrisnicola/src/aot-bug/src/app/app.component.ts, resolving symbol AppComponent in /Users/chrisnicola/src/aot-bug/src/app/app.component.ts
ERROR in ./src/main.ts
Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfactory' in '/Users/chrisnicola/src/aot-bug/src'
@ ./src/main.ts 4:0-74
@ multi ./src/main.ts
However the error message is referring to a function that is in fact exported in the file. The component code is below:
import { Component } from '@angular/core';
import {animate, transition, trigger, style, state} from "@angular/animations";
export function rotate(rotation = 180, animRotate = '400ms', animUnrotate = '400ms') {
let unrotated = style({ transform: 'rotate(0)' });
let rotated = style({ transform: `rotate(${rotation}deg)` });
return trigger(`rotate${rotation}`, [
state('unrotated', unrotated),
state('rotated', rotated),
transition('rotated => unrotated', [rotated, animate(animRotate, unrotated)]),
transition('unrotated => rotated', [unrotated, animate(animUnrotate, rotated)]),
]);
}
export function rotateState(rotated: boolean) {
return rotated ? 'rotated' : 'unrotated';
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [ rotate() ]
})
export class AppComponent {
title = 'app works!';
}
Expected behavior
It should compile, or if there is in fact an error in the code the error should state the problem correctly, since the function in question is in fact exported.
Minimal reproduction of the problem with instructions
Steps to reproduce:
- Start a new application like
ng new aot-bug
- Edit
app.component.ts
and use the code snippet above - Run
ng build -prod
What is the motivation / use case for changing the behavior?
Getting a working AoT for us in our project. We have been trying to get a working AoT build with our production code since version 2.0 with no luck.
Please tell us about your environment:
- Angular version: 4.0.0
- Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
-
Language: [all | TypeScript X.X | ES6/7 | ES5]
-
Node (for AoT issues):
node --version
= v6.9.1
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 5
- Comments: 20 (4 by maintainers)
Honestly it is ridiculous to me that this is even a problem. But then again that is why I switched to Vue.
So based on further testing it seems the things that are problematic are:
`rotate(${value}deg)`
. Concatenation works however.var
,const
orlet
in the function. Instead it must be extracted from the function and exported. Surprisingly, you can pass values as parameters and they can have defaults.These limitations seem both severe and inconsistent. Now that I’ve at least narrowed them down can someone from the Angular team chime in and let me know if they are: intentional and by design, short-term limitations that the team expects to overcome, or just simply bugs?
An additional problem I’ve noted, is that
ng server -aot
does not always seem to pick up changes when I’m testing these things and it often has to be restarted to compile properly again.@chrisnicola the issue is that the function isn’t being called by code, it’s being called as part of metadata, which looks like code but isn’t. Metadata needs to be fully resolved at compile time, not runtime.
If you actually want to execute code at runtime to produce a value to satisfy a provider, use
useFactory
:@alxhub sadly I think this just demonstrates that Angular’s AoT strategy isn’t a particularly good one.
The fact that code that is completely valid to the Typescript compiler doesn’t work with the AoT compiler seems like a pretty big limitation.
So sad to see that this problem is not yet solved, even with
Angular 4.2
animations, which are focused on making animations more reusable@jaesung2061 probably not the place for this discussion, but it’s been pretty great. It is somewhat familiar if you have experience with Angular 1.x. Sadly Vue feels like what Angular 2 should have been instead of this over designed attempt to make a javascript framework look more like a Java enterprise project.
@jiayihu, most of these are fine - the compiler can understand functions which immediately return a statically analyzable value, and invocations of those functions with statically analyzable (“foldable”) arguments.
Where the code you linked gets into trouble is with the
bounceInDirection
/bounceOutDirection
functions, which contain logic that violates the above rule (must return immediately). You might be able to rewrite them to be foldable. Inline conditionals (a ? b : c
) are okay. For example, here’sbounceOutDirection('x')
:then this is legal: