Repository navigation
1.0.1 -> 1.1.3 broke DI -- Uncaught Error: Can't resolve all parameters for providesGuard(?) #6788
Copy link
Copy link
Closed
Labels
needs: repro stepsWe cannot reproduce the issue with the information givenWe cannot reproduce the issue with the information given
Description
Bug Report or Feature Request (mark with an x)
- [x] bug report -> please search issues before submitting
- [ ] feature request
Versions.
macOS Sierra:
{ 'test-app': '0.0.0',
npm: '3.10.10',
ares: '1.10.1-DEV',
http_parser: '2.7.0',
icu: '58.2',
modules: '48',
node: '6.10.3',
openssl: '1.0.2k',
uv: '1.9.1',
v8: '5.1.281.101',
zlib: '1.2.11' }
Repro steps.
- Upgrade from version 1.0.1 to 1.1.3
npm run start(which isng serve)
The log given by the failure.
compiler.es5.js:1689 Uncaught Error: Can't resolve all parameters for providesGuard: (?).
at syntaxError (http://localhost:4200/vendor.bundle.js:18052:34)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getDependenciesMetadata (http://localhost:4200/vendor.bundle.js:32119:35)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getFactoryMetadata (http://localhost:4200/vendor.bundle.js:31999:51)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver.getProviderMetadata (http://localhost:4200/vendor.bundle.js:32272:43)
at http://localhost:4200/vendor.bundle.js:32193:49
at Array.forEach (native)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getProvidersMetadata (http://localhost:4200/vendor.bundle.js:32153:19)
at http://localhost:4200/vendor.bundle.js:31728:63
at Array.forEach (native)
at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver.getNgModuleMetadata (http://localhost:4200/vendor.bundle.js:31719:49)
Desired functionality.
Would like to know how to correct the ModuleWithProviders guard so that it's compatible going forward if this change in behavior between 1.0.1 and 1.1.3 is permanent. If it's a bug in 1.1.3, then a fix would be good. The work-around right now is to use 1.0.1.
Mention any other details that might be useful.
Here is a sanitized version of the module that reproduces the issue:
import {
NgModule,
ModuleWithProviders,
Inject,
InjectionToken,
SkipSelf,
Optional
} from '@angular/core';
// REST Service and Configuration
// IRestConfig is:
// export interface IRestConfig { port?: number; host?: string; apiUrl?: string; }
// REST_CONFIG is:
// export const REST_CONFIG = new InjectionToken<IRestConfig>('REST_CONFIG');
export { IRestConfig } from './shared/rest.config';
import { IRestConfig } from './shared/rest.config';
import { REST_CONFIG } from './shared/rest.service';
// Guard for providing RP
export const GUARD = new InjectionToken<void>('GUARD');
@NgModule({ })
export class TestModule {
static forRoot(config?: IRestConfig): ModuleWithProviders {
return {
ngModule: TestModule,
providers: [
{ provide: REST_CONFIG, useValue: config },
{
provide: GUARD,
useFactory: providesGuard,
deps: [
[ REST_CONFIG, new Optional(), new SkipSelf() ]
]
}
]
}
}
constructor(@Inject(GUARD) guard: any) { /** */ }
}
export function providesGuard(config: IRestConfig): any {
if (config) {
throw new Error('TestModule.forRoot() called twice.');
}
return 'guarded';
}
At the app module, one would add TestModule.forRoot({ port: 1234 }), for example, into the imports.
Changing from 1.0.1 to 1.1.3 of @angular/cli results in the error (at the browser) that the argument to providesGuard couldn't be resolved.
EDIT: Was missing code ticks ahead of the last block of code.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
needs: repro stepsWe cannot reproduce the issue with the information givenWe cannot reproduce the issue with the information given
Activity
filipesilva commentedon Jun 27, 2017
I think this isn't as much a CLI build problem as it is a runtime Angular problem. It sounds like a very similar situation to #2034.
You're using an interface as a DI token, which is an approach that has some problems. See #2034 (comment) for a more detailed answer about this.
Can you tell me if making
IRestConfiga class instead of an interface helps?btgoodwin commentedon Jun 27, 2017
filipesilva commentedon Jun 28, 2017
I can take a look if you can make a simple repro for this issue.
btgoodwin commentedon Jun 28, 2017
I'm pretty deep into the rabbit hole at this point.
The interface being defined in a different file and imported was ultimately the main issue even though using a class did nothing to rectify the problem (the other module is where the related service was configured, so this was originally an attempt at avoiding a circular dependency on the interface). I’ve since flipped that paradigm to the more standard approach of having the service be part of the ModuleWithProviders
forRootroutine. That resolved the error and left me with a different one about[object Object]was imported by the app module, etc. at runtime.This error is related to my development library having been linked into the app’s
node_modules(usingnpm link), and then, for whatever reason, this version of server pulling innode_modules/my_library -> /my_workspace/my_library/dist/../node_modules.One suggested "fix" is to delete the linked-in library's
node_modules, which means having a development environment where for anynpm linked library, it would requirenpm install && npm run build && rm -rf node_modulesevery time I wanted to make a change to that library. An actual more tenable fix modifying the CLI’s generatedtsconfig.app.jsonto include:However, now at runtime my library's use of
rxjs/add/operator/mapgets flagged as not a function. For example, in the library:The above would work fine before v1.1.3. In fact re-installing
@angular/cli@1.0.1all these modifications all work as expected. So as stated in my opening issue, the repro steps are install 1.1.3, watch lots of things break when runningng serve. Reinstall 1.0.1, watch everything work as expected.So while I agree that it's not necessarily a direct problem of running the transpiler, it certainly has something to do with these two versions of the CLI package. And even though I've now mitigated the original issue, it's pretty irrelevant because everything I fix to make this library to work with this version of the CLI-generated and served app just uncovers one more thing that is now broken, specifically for this version of the CLI package.
filipesilva commentedon Jul 3, 2017
Mind you, when I asked for repro steps I meant repro steps for me, not for you... when you say
repro steps are install 1.1.3, watch lots of things break when running ng serve.that kinda doesn't help me at all, because I don't have your projects nor your setup to see things break.There's some guidance on how to work with linked libraries here: https://github.com/angular/angular-cli/wiki/stories-linked-library. I'm not sure what your workflow is but you do need to build your library and not rely on the CLI to compile it for you. It maybe might work if you let the CLI compile it, but there's loads of scenarios where that won't work.
I think the PR where something changed that allowed your scenario to work was #6276, where we fixed some some more serious problems and then provided the linked lib guidance I linked above.
btgoodwin commentedon Sep 19, 2017
I apologize for my earlier terseness. I've used my above steps to generate a library and application from @angular/cli, which is now at 1.4.2 and also having the same problem. You can find the generated app and library here.
Your repro steps should be:
npm installin eachtestlib/distrunnpm linktestapp, runnpm link testlibtestapp,npm run start.The resulting directory structure looks like this:
When you open a browser to the server, Angular will exception out with:
The only solution, I've found, to work in a development environment with @angular/cli >1.0.1 is to modify the gulpfile of the library so that it is generated outside of the repository's top level directory (mimicking the deployment behavior).
../testlib-distso that the library builds outside its own project directory, away from the project'snode_modules.testapp).The resulting directory structure looks like this:
This prevents the server from traversing down into
testapp/node_modules/testlib/dist/../node_moduleswhen looking for installed node modules.From my perspective, all I "did" was upgrade from 1.0.1 to something newer of @angular/cli, and that's when the directory traversal behavior changed, breaking the previously-working method of linking a development library's distribution directory into an application. And the break occurred because the server (in my opinion, erroneously) starts looking in subdirectories of the app's
node_modulesfor morenode_modulespaths.angular-automatic-lock-bot commentedon Sep 7, 2019
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.