I have a library material-extension inside my angular workspace, in which I'm creating some components I require but Angular Material is lacking. In this extension I've installed the module ngx-editor, which I require in the library components but not in the project itself. ngx-editor seems to also have automatically installed angular itself as one of its dependencies, so I've also ended up with @angular in the node_modules folder of my library.
So I've ended up with this structure:
- workspace
- node_modules
- @angular
- @angular\material
- projects
- angular\material-extension
- file-upload
- node_modules
- @angular
- ngx-editor
- text-editor
- world-builder
- src
- angular\material-extension
- node_modules
I have worked with angular 14 in the past and am now using angular 18, trying to rewrite some old module based code into the new standalone with signals and injection function. I have one instance where I'm creating a custom material dialog, which uses an injection token according to the Angular Material documentation.
To access the data in your dialog component, you have to use the MAT_DIALOG_DATA injection token:
import {Component, Inject} from '@angular/core'; import {MAT_DIALOG_DATA} from '../dialog'; @Component({ selector: 'your-dialog', template: 'passed in {{ data.name }}', }) export class YourDialog { constructor(@Inject(MAT_DIALOG_DATA) public data: {name: string}) { } }
Which I'm trying to rewrite according to Angular documentation on migration to the inject function.
Before
constructor( @Inject(DI_TOKEN) @Optional() readonly token: string) {} }After
readonly token = inject(DI_TOKEN, { optional: true });
So in my case particularly, that is from my old
constructor(dialogRef: MatDialogRef<MatTextEditorDialogComponent>,
@Inject(MAT_DIALOG_DATA) data: any) {
this.color = 'primary';
this._dialogRef = dialogRef;
}
to the new
import { Component, inject, input, InputSignal } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { ThemePalette } from '../../../../../../dist/angular/material-extension';
@Component({ template: '' })
export abstract class Dialog {
public color: InputSignal<ThemePalette> = input<ThemePalette>('primary');
private _dialogRef: MatDialogRef<Dialog> = inject(MatDialogRef<Dialog>);
public data: any = inject(MAT_DIALOG_DATA);
public close(): void {
this._dialogRef.close();
}
}
However, I'm facing an error here, saying Argument of type 'InjectionToken<any>' is not assignable to parameter of type 'ProviderToken<any>'., which I assume happens due to the fact that MAT_DIALOG_DATA is imported from the workspace's @angular/material node_module folder (as the library doesn't have angular material installed), while the inject() method is imported from the library's own node_module, which works with the library's instance of @angular/core and thus considers the two incompatible (though I do wonder why the MatDialogRef injection works then...?).
I have worked with Angular's modular approach in the past but am kinda new to the standalone app structure. With modules, each module had its own imports so it made sense to install external modules in library projects (or at least in the library). I'm not sure how to handle this in a standalone app though. Is it even the way to go to have separate node_module folders for a library or should everything just be installed in the workspace? In the former case, how could I tell the library to use the workspace's @angular/core instead of its own? Just remove it from the node_modules folder?
UPDATE:
There was indeed a mismatch between the angular versions in the workspace and the library, the former was @18.1.0 while the latter was @18.2.0.
I've updated the workspace minor version using the command npx npm-check-updates --upgrade --target "minor" --filter "/@angular.*/" I found in this post, which resulted in the following updates:
@angular-devkit/build-angular ^18.2.7 → ^18.2.15
@angular/animations ^18.1.0 → ^18.2.13
@angular/cdk ^18.2.6 → ^18.2.14
@angular/cli ^18.2.0 → ^18.2.15
@angular/common ^18.1.0 → ^18.2.13
@angular/compiler ^18.1.0 → ^18.2.13
@angular/compiler-cli ^18.1.0 → ^18.2.13
@angular/core ^18.1.0 → ^18.2.13
@angular/forms ^18.1.0 → ^18.2.13
@angular/material ^18.2.6 → ^18.2.14
@angular/platform-browser ^18.1.0 → ^18.2.13
@angular/platform-browser-dynamic ^18.1.0 → ^18.2.13
@angular/platform-server ^18.1.0 → ^18.2.13
@angular/router ^18.1.0 → ^18.2.13
@angular/ssr ^18.2.7 → ^18.2.15
With this I was able to ng build my app, but it did not resolve the error. Also, I was now unable to build a different library project, "file-upload" (please see the updated project structure), which doesn't require any additional external modules. The error message I receive is:
✖ Compiling with Angular sources in Ivy partial compilation mode.
Cannot destructure property 'pos' of 'file.referencedFiles[index]' as it is undefined.
I've tried to look for a solution to this but other than a couple different options to try I found here of which none applied to me I couldn't find anything else.
- I have no
"composite": "true"in either the workspace's tsconfig.json nor the project's tsconfig.app.json - I have no double relative paths in the tsconfig.json
- I am not referencing an app component inside the library
- I am not referencing a file outside of the library
The file-upload library project worked fine until recently (without any changes), though I can't quite say what exactly broke it, as I didn't have to build it for quite a while. As it doesn't require any external module, I've uninstalled everything in the library itself to make sure there's no accidental reference of the library's modules instead of the workspace's one as it should be and reverted any changes to the library's package.json, but this didn't change anything.
I've noticed the package-lock.json didn't seem to have been updated properly (there were still all the 18.1.x Angular modules in there, so I've deleted it and installed it again using the command found in this post:
npm i --package-lock-only
This updated the package-lock.json but I still can't get rid of this Ivy partial compilation mode error.