Search code examples
angulartokenaot

Tokenizing for AoT compilation


I've been having some issues with the inconsistencies between the JIT and AoT compilers. The most recent error that has stumped me was Error: Can't resolve all parameters for IndexedDBCache. IndexedDBCache is a service that depends on a string parameter:

Please note this issue also arises when I remove the 'protected' property!

// indexeddb-cache.ts
import { Injectable } from '@angular/core';

@Injectable()
export class IndexedDBCache {
  constructor(protected databaseName : string) {}
}

I'm using a factory to provide versions of the service:

// test-api.cache.factory.ts
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';

export function testIndexedDBCacheFactory() { return new IndexedDBCache('test'); }

// test-api.cache.ts
import { InjectionToken, Provider } from '@angular/core';
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';
import { testIndexedDBCacheFactory } from './test-api.cache.factory';

export const testIndexedDBCache = new InjectionToken<IndexedDBCache>('testIndexedDBCache');

export let testIndexedDBCacheProvider : Provider = {
  provide: testIndexedDBCache,
  useFactory: testIndexedDBCacheFactory
};

Note : These files have to be split according to func-in-providers-useFactory and arrow-function-exports - don't ask me why =/

Now the AoT compiler doesn't like this string paramter at all. I've looked into the issue but could only find reference to OpaqueToken (now depricated and replaced by InjectionToken<string>). My code would now read:

// test-api.cache.factory.ts
import { InjectionToken } from '@angular/core';
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';

const testIndexedDBCacheFactoryToken = new InjectionToken<string>('test');
export function testIndexedDBCacheFactory() { return new IndexedDBCache(testIndexedDBCacheFactoryToken); }

Obviously this is not compiling as the constructor would only allow for a string parameter. I don't have enough knowledge about InjectionTokens or the AoT issue at hand to solve this - anyone have a suggestion for a construct that would work?

More context on my code and issue to be found at angular/angular#17295.


Things I've tried:

  1. Removing the protected access modifier > Exact same error persists
  2. Removing the string parameter > Not an option - it defines the service
  3. Replacing the string parameter in the factory with an InjectionToken<string> > An InjectionToken is not a suitable parameter

Solution

  • There was a misunderstanding of the issue at hand. The classes to be factoried are not services themselves and as such do not need the @Injectable property. More detail to be found at Creating AoT compatible Service Factories