ngforage
ngforage copied to clipboard
Compilation error Angular 7 and 8 in AoT
- [x] I have read the README and API docs (if applicable); the issue is not covered there.
- [x] I have searched the repository issues and pull requests; my query is not covered there.
- Expected behaviour: build success
- Actual behaviour: build failed
-
Environment:
- Node version: 8.12.0
- Browser and browser version (if applicable): Chrome
- Steps to reproduce:
npm i
npm run build
ERROR in Error during template compile of 'AppModule' Function calls are not supported in decorators but 'NgForageModule' was called.
- Reproducible code sample:
Additional information, screenshots etc go here.
Yeah, I've gotten this bug too but I have no idea why after hours of debugging and trying out various solutions by people with similar issues. At the moment it appears to be a regression from Angular 6 as the module hasn't changed (4.0.0 | 3.4.0).
If you have any solutions do let me know please!
You can get around it for now, though. NgForage consists only of services, so importing the module isn't actually necessary; you can simply perform the default configuration in your AppModule's constructor:
import {BrowserModule} from '@angular/core';
import {NgForageConfig} from 'ngforage';
@NgModule({imports: [BrowserModule]})
export class AppModule {
public constructor(ngfConfig: NgForageConfig) {
ngfConfig.configure(configurationOptions);
}
}
Issue reported here: https://github.com/angular/angular/issues/23609#issuecomment-433450395
Since moving to Angular 7 and then needing to apply the workaround from @Alorel, i am having the issue of my dedicated instance factory which was only changing the store is now no longer picking up my config from the app module.
export class AppModule {
public constructor(ngfConfig: NgForageConfig) {
ngfConfig.configure({
name: 'DatabaseName1',
storeName: 'App',
driver: [
Driver.INDEXED_DB,
Driver.WEB_SQL,
Driver.LOCAL_STORAGE
]
});
}
}
requests made using the standard import works fine, and saves to this database in the LocalDB however in one of my services i have:
private ngfw: NgForage;
constructor(private http: HttpClient, private userOptions: UserOptionsService,
ngfdif: DedicatedInstanceFactory) {
this.ngfw = ngfdif.createNgForage({storeName: 'Other'});
}
all requests made to the ngfw are being saved to ngForage Database not the DatabaseName1
@Dedme I can't seem to reproduce the error.
app.module.ts
@NgModule({
imports: [
BrowserModule
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {
public constructor(ngfc: NgForageConfig) {
ngfc.configure({
name: 'mamc',
driver: [
Driver.LOCAL_STORAGE
]
});
}
}
app.component.ts
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
public constructor(private readonly diFactory: DedicatedInstanceFactory) {
const ngf = diFactory.createNgForage({name: 'eyy'});
console.dir(ngf);
// finalCOnfig correctly shows name as 'eyy' and driver as [localstorage]
}
}
I understand that this is a messier solution than the one that was available for ng6, but we have to work with what we can, unfortunately. I've made the injection token provided by NgForageModule.forRoot()
exported and non-internal in ngforage 4.0.1, allowing you to achieve forRoot()
functionality without actually calling forRoot()
:
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {DEFAULT_CONFIG, NgForageOptions} from 'ngforage';
const ngfRootOptions: NgForageOptions = {
name: 'DatabaseName1',
// ... other config options
};
@NgModule({
imports: [BrowserModule],
providers: [{
provide: DEFAULT_CONFIG,
useValue: ngfRootOptions
}]
})
export class AppModule {}
Can you try that out and let me know if it solves your issue please? I'll then update the README accordingly.
import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {DEFAULT_CONFIG, NgForageOptions} from 'ngforage'; const ngfRootOptions: NgForageOptions = { name: 'DatabaseName1', // ... other config options }; @NgModule({ imports: [BrowserModule], providers: [{ provide: DEFAULT_CONFIG, useValue: ngfRootOptions }] }) export class AppModule {}
Can you try that out and let me know if it solves your issue please? I'll then update the README accordingly.
Thanks for this. works great!!! i did realise i had ngforage being imported as a provider in my appmodule, but after removing this is still had my same issue.
also without using the provider method, which i am perfectly okay with as it seems to be the new standard that i am seeing everywhere, i did end up with an empty 'ngforage' database. so it seemed to be getting initialised before the constructor could set its config.
thanks for the fast feedback!
Same issue for me... Thanks for your workaround @Alorel !
Hi everyone!
I have a problem with AOT compilation in Angular 7.1. I have tried config ngForage in both of presenting ways. The first was into it in AppModule constructor, and second one as a provider (with DEFULT_CONFIG). Unfortunately, when I use ngForage:
ngOnInit(){
this.forage.storeName = 'MyStorage;
this.forage.setItem('key','value');
}
forage is NgForage as Dependency Injection in the constructor.
During the building isn't any errors. Then, after load the website, I have a one error in the console:
This happened only if I have built it with aot option.
Do you know what I am doing wrong? Or is there any workaround?
@weronikasabiniewicz I'm terribly sorry, this is embarrassing, but I completely missed your reply... I wasn't able to reproduce your issue - have you set the library up exactly as stated in the instructions? Do you have localforage
installed? Perhaps you misconfigured something? I generated a new project with the CLI, tried your ngOnInit
, and everything worked fine.
app.component.ts:
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {NgForage} from 'ngforage';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
public ngfValue: string;
public constructor(
private readonly ngf: NgForage,
private readonly cdr: ChangeDetectorRef
) {
}
public ngOnInit() {
const k = 'ngf-test-date-value';
this.ngf.storeName = 'ngf-test-date-store';
this.ngf.setItem(k, new Date().toLocaleString())
.then(() => this.ngf.getItem<string>(k))
.then(v => {
this.ngfValue = v;
this.cdr.markForCheck();
return this.ngf.removeItem(k);
})
.catch(console.error);
}
}
app.component.html:
<div *ngIf="ngfValue; else default">Ngforage returned {{ngfValue}}</div>
<ng-template #default>Loading</ng-template>
app.module.ts:
// unmodified
Could you create a repo that reproduces the issue on https://stackblitz.com and create a separate issue please?
I've tried reproducing the initial AOT compilation issue in the upcoming Angular 8 PR and, unfortunately, the issue is still there with no updates from the Angular team apart from "this'll get fixed with Ivy" (which wasn't fully released with Angular 8 yet).
Should I use this solution as a workaround at this time?
Changes in app.module.ts
:
import {Driver, NgForageOptions, DEFAULT_CONFIG} from 'ngforage';
...
const ngfRootOptions:NgForageOptions = {
name: 'next-storage',
driver: [
Driver.INDEXED_DB,
Driver.WEB_SQL,
Driver.LOCAL_STORAGE
]
};
...
providers: [
{
provide: DEFAULT_CONFIG,
useValue: ngfRootOptions
}
...
]
...
Source: https://stackoverflow.com/a/56741945/1979190
@weronikasabiniewicz I'm terribly sorry, this is embarrassing, but I completely missed your reply... I wasn't able to reproduce your issue - have you set the library up exactly as stated in the instructions? Do you have
localforage
installed? Perhaps you misconfigured something? I generated a new project with the CLI, tried yourngOnInit
, and everything worked fine.app.component.ts:
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit} from '@angular/core'; import {NgForage} from 'ngforage'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { public ngfValue: string; public constructor( private readonly ngf: NgForage, private readonly cdr: ChangeDetectorRef ) { } public ngOnInit() { const k = 'ngf-test-date-value'; this.ngf.storeName = 'ngf-test-date-store'; this.ngf.setItem(k, new Date().toLocaleString()) .then(() => this.ngf.getItem<string>(k)) .then(v => { this.ngfValue = v; this.cdr.markForCheck(); return this.ngf.removeItem(k); }) .catch(console.error); } }
app.component.html:
<div *ngIf="ngfValue; else default">Ngforage returned {{ngfValue}}</div> <ng-template #default>Loading</ng-template>
app.module.ts:
// unmodified
Could you create a repo that reproduces the issue on https://stackblitz.com and create a separate issue please?
@Alorel Hi,
I have created code on https://stackblitz.com and it looks fine. I have to check my old code written in Angular 7.1 and I will back to you.
Thanks for response.
Should I use this solution as a workaround at this time?
Changes in
app.module.ts
:import {Driver, NgForageOptions, DEFAULT_CONFIG} from 'ngforage'; ... const ngfRootOptions:NgForageOptions = { name: 'next-storage', driver: [ Driver.INDEXED_DB, Driver.WEB_SQL, Driver.LOCAL_STORAGE ] }; ... providers: [ { provide: DEFAULT_CONFIG, useValue: ngfRootOptions } ... ] ...
Yeah, to give a recap, this issue was a regression in Angular when moving from ng6 to ng7 even though nothing had changed in this library. It was supposed to get fixed with the Ivy compiler, but that still hasn't arrived so we need to provide the configuration at the moment. If the issue persists in Angular 9, I'll just remove the forRoot API.
Hi guys the DEFAULT_CONFIG
exporting is missing when installing through npm install localforage@^1.5.0 ngforage@^4.0.0 # Angular 7
(I've checked the files and the export is really missing).
Solved by using npm install ngforage@ng7
.