I'm submitting a ...
[x] bug report
Current behavior
Compiling an application with the angular AOT compiler fails, when ng2-translate is included in the module. The following import leads to an error:
...
imports: [TranslateModule.forRoot()]
...
Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function
Expected/desired behavior
It should compile successfully.
Please tell us about your environment:
Hello, thanks for the report !
I haven't had the chance to use the AoT compiler because it was not working on windows... it does now with rc6 so I will try and fix this
Any updates on this?
I still cannot use TranslateModule.forRoot() with AOT compiler (ngc). Keep getting "Error encountered resolving symbol values statically".
Any help here would be greatly appreciated.
Same issue for me, I keep getting this error even with version 2.5.0 and angular 2.0.0 on macOS.
This is a bummer. Does anyone have an idea why it's still not working after the previous PR? Let's help each other out. We're all on the same boat :).
I basically tried it with a bare minimum example. Just to see what it did:
@NgModule({})
export class TranslateModule {
static forRoot() {
}
}
It just doesn't work. It still shows the error
Error: Error encountered resolving symbol values statically. Function calls are not supported.
@robwormald Any ideas?
@SamVerschueren can you try your minimal example with forRoot returning a ModuleWithProviders ?
Alright, after fiddling around with this I think the issue is that we don't have a metadata.json file which seems to be required for AOT. Basically this means that the library should be compiled with ngc as well. I tried doing that and I got a metadata.json file, but it didn't work yet entirely.
Extra notes.
When using the master branch (don't see any improvement with the npm package though), I managed to get another error.
Error: Unexpected value 'TranslateModule' exported by the module 'SharedModule'
And Google shows me that it has something to do with the metadata file.
What was I doing wrong in the first place? If you provide a loader yourself, (1) make sure it uses a function as well and (2), it is exported.
// The `export` seems to be an important piece of the puzzle
export function translateLoaderFactory(http: any) {
return new TranslateStaticLoader(http, 'app/shared/i18n', '.json');
}
@NgModule({
imports: [
TranslateModule.forRoot({
provide: TranslateLoader,
useFactory: translateLoaderFactory,
deps: [Http]
})
]
})
export class AppModule { }
This only helped with the code in master, not the one on npm. Not sure if you made any changes since the latest release?
Wow thanks for the hard work @SamVerschueren
Having to compile all external libs to make them compatible with AoT seems like a really bad design in my opinion, there's no way every lib author knows that he has to do that, and it means that if you want to do AoT you cannot use an external lib that isn't AoT compatible...
I think it's time to call the A-Team to get a real idea of what's going on: @robwormald @vicb @mhevery @alexeagle @vsavkin any idea on this? How can we make an external lib work with the AoT compiler? Are we on the wrong path here, or should the lib really be pre compiled before distribution?
Yes, I might be very wrong here. Very new to the AoT stuff.
Ok I've got the confirmation from @brandonroberts that if we want the library to be AoT compatible, it should be pre compiled and the metadata files published on npm, I'll work on that and try to make a working release
Here is an example of a lib with AoT: https://github.com/brandonroberts/aot-library/tree/aot
And the app using the lib: https://github.com/brandonroberts/aot-app/tree/aot
Thanks for looking into this @ocombe !
@robwormard is planning to write docs. Correct that you need to publish
*.{js,metadata.json,d.ts,js,map} tuples, and also add some integration
testing that an app with AoT can actually consume the library.
For the latter we are cheating right now, ng2-material should test this on
their own travis, but instead we have a test on angular/angular that npm
install's the material-button and asserts that the example app can be AoT
compiled.
I think angular-team could do more to help the CI story, like give a
service that tests components and provides a badge to add on your page.
Don't think anyone has time to work on that though, maybe we need a
community contrib.
Nice, thanks :)
I already told the docs team to add a note about this in the upcoming AoT guide (the design doc can be found here: https://docs.google.com/document/d/1MwdXSnqBwuresNDcdUklSK7ILSUJtlkIIy_jRURKPVA/edit#heading=h.o0y7rkw1hvru)
I wrote up an article with steps to add *.metadata.json files to your library. I agree that documentation is lacking, and most library authors have no idea this is required.
Any update on this? Do we have any way now to use ng2-translate with AOT?
Not yet, I was too busy with angular connect :(
I'll do it this week end !
No hurry @ocombe. Take a look whenever you find the time!
Actually @SamVerschueren, if @ocombe could take a look to that problem that would be much great. If I understand correctly that there is no solution to use ng2-translate with AoT, all people who migrated to Ionic 2 RC since yesterday and who are using ng2-translate are blocked because of that issue :(
I've written another article that goes through solutions to some of the errors (including the Function calls are not supported error) I've run into updating libraries to be AoT compatible.
@peterpeterparker I understand that it might be urgent for some people. But you must know that @ocombe is doing this in his spare time, like most of the open source contributors. If you want this so badly, nothing stops you from contributing and doing a decent PR yourself. Open source is not the same as consultancy for free. And that's what I meant with my comment. @ocombe should solve this when he finds the time to solve it or someone else should jump in and help him out.
that's why I wrote "would be much great"
I got it working last night. I am using it in an Ionic 2 RC0 project, so i don't know if it will work for everybody.
1 I build the plugin using the steps described in this article by @isaacplmann
2 I copied the over the newly generated files over the original files from the NPM repo in my project
3 I added the following to the to the /node_modules/@ionic/app-scripts/config/rollup.config.js
commonjs({
namedExports: {
'node_modules/ng2-translate/ng2-translate.js': [ 'TranslatePipe', 'TranslateLoader', 'TranslateStaticLoader', 'TranslateService' ]
}
})
This was the suggestion of peelfresh on the ionic forum
4 I added the following code to the @ngModule:
export function translateLoaderFactory(http: any) {
return new TranslateStaticLoader(http, 'assets/i18n', '.json');
}
import section:
TranslateModule.forRoot(
{
provide: TranslateLoader,
useFactory: translateLoaderFactory,
deps: [Http]
}
)
5 For the import statements i used:
import {TranslateModule} from "ng2-translate/ng2-translate";
import {TranslateService, TranslateLoader, TranslateStaticLoader} from "ng2-translate/src/translate.service";
I hope this makes sense, because it was a very long day yesterday to get it sort of working
@krizroring this solution works fine in browser but if you try build a platform app, the compilation fails. In my app I use only two languages and I made a easy workaround : I created a @Pipe with same name of @ocombe lib where I use a JSON file like a static var. In the future I will have to change the include lib with the new release without modify the html template
Yeah, I did the same as @krizroring. Also if you you use ts.instant you can write a mockup services for that as well.
I tested it in an Ionic ios app, and mu solution worked. Could be that i
did some more thing to get it working, but like i said, it was very late :)
On Friday, 30 September 2016, flolovebit [email protected] wrote:
@krizroring https://github.com/krizroring this solution works fine in
browser but if you try build a platform app, the compilation fails. In my
app I use only two languages and I made a easy workaround : I created a
@Pipe https://github.com/Pipe with same name of @ocombe
https://github.com/ocombe lib when I use a JSON file like a static var.
In the future I will have to change the include lib with the new release
without modify the html template—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/ocombe/ng2-translate/issues/218#issuecomment-250700405,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEH4BLwlXQYV4db8sh8XvfPFQK8HcRJeks5qvNXTgaJpZM4Jx_qT
.
@flolovebit could you explain me how to create this pipe, so I can build my app without having to rewrite all my templates, while the ng2-translate does not work with the ionic2' rc?
The just pulled version (3.0.0) fix AoT problem for me :tada:
Work like a charm in Ionic 2 RC.0!
Thx @ocombe <3
I'm still having issues to get this working in Ionic 2 RC.0.
I've started over from a fresh app to try to figure it out, but no success.
I'm using ng2-translate v3.0.0.
Here's my app.module.ts :
import {BrowserModule} from "@angular/platform-browser";
import { NgModule } from '@angular/core';
import {HttpModule} from '@angular/http';
import { IonicApp, IonicModule } from 'ionic-angular';
import {TranslateModule} from 'ng2-translate/ng2-translate';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
@NgModule({
declarations: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage
],
imports: [
IonicModule.forRoot(MyApp),
BrowserModule,
HttpModule,
TranslateModule.forRoot()
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage
],
providers: []
})
export class AppModule {}
app.component.ts:
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from 'ionic-native';
import {TranslateService} from 'ng2-translate/ng2-translate';
import { TabsPage } from '../pages/tabs/tabs';
@Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage = TabsPage;
constructor(platform: Platform, translate: TranslateService) {
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');
// the lang to use, if the lang isn't available, it will use the current loader to get them
translate.use('en');
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
});
}
}
I'm not using ng2-translate anywhere else in my code at the moment.
Here's the error I have at compilation (ionic run android):
[12:22:26] ngc error: Error: Error at /media/data/dev/myApp/.tmp/app/app.module.ngfactory.ts:96:27: Cannot find module '../../src/translate.service'.
Error at /media/data/dev/myApp/.tmp/app/app.module.ngfactory.ts:397:94: Property 'translateLoaderFactory' does not exist on type 'typeof "/media/data/dev/myApp/.tmp/app/app.module"'.
at check (/media/data/dev/myApp/node_modules/@angular/tsc-wrapped/src/tsc.js:31:15)
at Tsc.typeCheck (/media/data/dev/myApp/node_modules/@angular/tsc-wrapped/src/tsc.js:86:9)
at /media/data/dev/myApp/node_modules/@angular/tsc-wrapped/src/main.js:33:23
at process._tickCallback (internal/process/next_tick.js:103:7)
at Function.Module.runMain (module.js:577:11)
at startup (node.js:160:18)
at node.js:456:3
I don't see what I'm missing.
Any Ionic user who could help me out?
Thanks guys!
@TdyP I think it is a bug but you can workaround it by defining translateLoaderFactory. This worked for me:
import {TranslateModule, TranslateStaticLoader} from "ng2-translate/ng2-translate";
import {TranslateLoader} from "ng2-translate";
export function translateLoaderFactory(http: any) {
return new TranslateStaticLoader(http, './assets/i18n', '.json');
}
@NgModule({
imports: [
IonicModule.forRoot(MyApp),
HttpModule,
TranslateModule.forRoot({
provide: TranslateLoader,
useFactory: translateLoaderFactory,
deps: [Http]
}),
If you change './assets/i18n' to './i18n' you should get the default behaviour I guess.
@apreg You're right!
@TdyP It's not a bug from ng2-translate it self, and it's not a bug anymore.
Angular 2 need to have reference to this function when compiling it. See here (https://github.com/angular/angular/issues/10789#issuecomment-242220591)
Here it's working fine with 3.0.0 and Ionic 2 rc 0 :-)
@apreg @TdyP I noticed that in your example you have a './' before 'assests/i18n' in your function declaration. Don't know if you gonna face the same problem as I did, but in my case, because I had '/' before 'assests/i18n', the translation weren't load on my device when I was running my app 'irl'.
So in my case to fix that, the function look like this:
export function translateLoaderFactory(http: any) {
return new TranslateStaticLoader(http, 'assets/i18n', '.json');
}
If you use /assets/i18n it will try to load the language files from the root of your app space. You have to put a dot in the beginning or ommit the slash to loads it from the correct place. So you have to use
export function translateLoaderFactory(http: any) {
return new TranslateStaticLoader(http, './assets/i18n', '.json');
}
if your language files are stored in src/assets/i18n folder.
Maybe this should have been added to the README.
@NoNameProvided well then at least not in my case. Was just writing that down because I lost hours just for a point ;)
If you use /assets/i18n it will try to load the language files from the root of your app space.
That's what I experienced so I played with the uri till it worked and this was the result.
@apreg coolio :) as I say, just wrote it down in case someone face the same issue as I did.
I did not mean it offensive or something don't get me wrong :D
It works like a charm with the exported function, thanks you very much guys! :)
Terribly sorry but
export function createTranslateLoader(http: Http) {
return new TranslateStaticLoader(http, 'assets/i18n', '.json');
}
@NgModule({
imports: [
TranslateModule.forRoot({
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
})
]
})
still yields
Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider
replacing the function or lambda with a reference to an exported function (position 72:25 in the original
.ts file), resolving symbol AppModule in /app/.tmp/app/app.module.ts
[19:53:05] ngc failed
[19:53:05] ionic-app-script task: "build"
[19:53:05] Error: Error
package json excerpt:
"dependencies": {
"@angular/common": "2.1.1",
"@angular/compiler": "2.1.1",
"@angular/compiler-cli": "2.1.1",
"@angular/core": "2.1.1",
"@angular/forms": "2.1.1",
"@angular/http": "2.1.1",
"@angular/platform-browser": "2.1.1",
"@angular/platform-browser-dynamic": "2.1.1",
"@angular/platform-server": "2.1.1",
"@ionic/storage": "1.1.6",
"@types/async": "^2.0.32",
"@types/lodash": "^4.14.38",
"@types/underscore": "^1.7.33",
"angular2-jwt": "^0.1.25",
"async": "^2.1.2",
"ionic-angular": "2.0.0-rc.3",
"ionic-native": "2.2.3",
"ionicons": "3.0.0",
"lodash": "^4.16.6",
"ng2-translate": "^3.1.3",
"rxjs": "5.0.0-beta.12",
"shortid": "^2.2.6",
"underscore": "^1.8.3",
"zone.js": "^0.6.26"
},
"devDependencies": {
"@ionic/app-scripts": "^0.0.45",
"@types/core-js": "^0.9.34",
"@types/shortid": "0.0.28",
"@types/underscore": "^1.7.33",
"shortid": "^2.2.6",
"typescript": "2.0.6",
"underscore": "^1.8.3",
"uuid": "^2.0.3"
},
@barocsi
export function exportTranslateStaticLoader(http: Http) {
return new TranslateStaticLoader(http, './assets/i18n', '.json');
}
TranslateModule.forRoot(
{
provide: TranslateLoader,
useFactory: exportTranslateStaticLoader,
deps: [Http]
}
),
no luck :(
just installed version 3.2.1 with my above code works fine for me (same angular version, ionic 2 rc.2 not 3)
I am using rc.3 and downgrading is not an option unfortunately
could give you a feed in a couple of days when after I'll upgrade to RC.3, but don't think that could be the problem since the angular version doesn't changed
It works, thanks. Figured out there were another lambda function within the app.module.ts
Hello
I'am using angular CLI, i'am able to compile in AOT but when i want to access the web site i have a 404 error like this one:
zone.js:1561 GET http://localhost/app/membership/i18n/en.json 404 (Not Found)
Is it because i don't put my translation files into assets ?
Thank you for your feedback
@Je06610 Make sure your path in the static loader is pointing to the correct location
@NgModule({
imports: [
BrowserModule,
HttpModule,
TranslateModule.forRoot({
provide: TranslateLoader,
useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
deps: [Http]
})
],
bootstrap: [AppComponent]
})
export class AppModule { }
As you can see, ng2-translate looks for the files in app/membership/i18n/en.json. Are those files really there? Most of the time this is due to the fact that those json files aren't automatically copied over to the dist directory. Not sure how the CLI handles that.
@SamVerschueren
Thank you for your advice.
The path is correct, it works perfectly without AOT but i don't use the standard path.(assets...)
I have a i18n folder for each module of my application and i think you are right the files are not copied but i don't know why...
Thanks so much. work very fine
Most helpful comment
Actually @SamVerschueren, if @ocombe could take a look to that problem that would be much great. If I understand correctly that there is no solution to use ng2-translate with AoT, all people who migrated to Ionic 2 RC since yesterday and who are using ng2-translate are blocked because of that issue :(