Closed Tallyb closed 4 years ago
Are you using Angular? Can you please post a snippet with injector?
@Injectable()
export class CoreConfig implements ICoreConfig {
private configConstants: any = {};
constructor(@Inject(PLATFORM_ID) private platformId, @Inject(CORECONFIG_CONSTANTS) config, protected swUpdate: SwUpdate) {
this.configConstants = config;
}
It is not clear from the plugin documentation if it works on constructor parameters or on the class itself.
Fixed in @hqjs/babel-plugin-add-type-metadata@0.0.4. Just reinstall @hqjs/hq to get latest version of plugins. I will release new hq version eventually with couple of other updates.
It works on constructor parameters, check the example for details.
Sadly, this only supports the unknown error. The problem is deeper, since then I get the following error
compiler.map:2387 Uncaught Error: Can't resolve all parameters for CoreConfig: (?, ?, [object Object]). at syntaxError (compiler.map:2387)
This is resulting from https://github.com/angular/angular/blob/d1ea1f4c7f3358b730b0d94e65b00bc28cae279c/packages/compiler/src/metadata_resolver.ts#L985
Trying to further think about the issue, doesn't Angular need to be compiled (not bundled, but compiled) in order to run in the browser. Especially with Angular 9/10 and Ivy? While searching on it, I have noticed this project in the Angular cli team: https://github.com/angular/angular-cli/tree/master/packages/ngtools/webpack. I wonder if that can be useful.
It means it expects some type metadata for injection. Angular does not need to be compiled on the server, it can be interpreted on the client. I have working examples for Angular (tour of heroes work without any issues).
Do you have any open minimal project so I can debug it and fix? Will check latest angular with ToH (last tested it with version 8)
Just tried it with https://github.com/ganatan/angular-example-starter and it works like a charm. I need an example to break it and find the solution.
In fact, the code above is using standard angular injectors and a custom one. This can probably be added to the repro of the TOH:
import { isPlatformServer } from '@angular/common';
import { Inject, Injectable, InjectionToken, PLATFORM_ID } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
const CORECONFIG_CONSTANTS = new InjectionToken<any>('CoreConfigConstants');
@Injectable()
export class CoreConfig implements ICoreConfig {
private configConstants: any = {};
constructor(@Inject(PLATFORM_ID) private platformId, @Inject(CORECONFIG_CONSTANTS) config, protected swUpdate: SwUpdate) {
this.configConstants = config;
}
How can we derive a type for platformId
and config
in this case? What your IDE says?
I found this example on official documentation
constructor(@Inject(APP_CONFIG) config: AppConfig) {
this.title = config.title;
}
But as you can see they still provide some typings.
Can you please assist with that issue. I'm not really sure what too look for. My guess is we should specify types for platformId
and config
or derive them somehow. I'm not an Angular developer, but would be happy to hack into it again, just need decent example and some guidance/documentation of how it supposed to work.
But the question is - should you assume that type information is always provided? Can this be bypassed when no type info is provided?
Well, as you can see from the error Angular requires some type metadata to be passed. It is either derived from the code or some kind of any
is used instead. If I have a working example - I would run it with hq
, backtrack to the place where this information is passed (I know that there would be null
for the missed types, but it would help to recognize the place) and then rerun it with angular compiler to see what is the difference (it is a bit tricky as angular compiler removes and transforms part of the code, but dependency injection part should remain).
@Tallyb can you please help with the example?
Hi, You can see the error in this repo: https://github.com/Tallyb/hq-angular
@hqjs
hi, got a chance to look at it?
Hey! Not yet. Have very busy time at work, sorry. Will try to check during the week.
Ok. Since my vacation was ruined I finally found some time to debug an issue. @Tallyb thanks again for posting an example. After some investigation I found that providers metadata should consist of an object with provide
property equal to a class, not a class itself. by changing it in debugging console I was able to run your example. Let me dive deeper to see how to turn meta into this object, seems like it should not be hard.
I'm preparing a fix for @hqjs/babel-plugin-add-decorators-metadata
.
Before I push anything @Tallyb are you sure it is correct syntax for providers after Angular version 6? Shouldn't it be turned into
providers: [{
provide: CoreConfig
}]
Fixed in the plugin https://github.com/hqjs/babel-plugin-add-decorators-metadata
. Just reinstall hq
to get updated plugin version.
Error in @hqjs/babel-plugin-add-type-metadata on this line: https://github.com/hqjs/babel-plugin-add-type-metadata/blob/master/index.js#L11 Injectors may not have typeAnnotation, so it fails