I want to add a CSS class dynamically on the click of a button on the body tag. So I am using the DOCUMENT object of angular. Here is the code
import { DOCUMENT } from "@angular/platform-browser";
... component code
constructor( @Inject(DOCUMENT) private document: Document) { }
addClass() {
this.document.body.classList.add("any_class");
}
but this is showing errors
Metadata collected contains an error that will be reported at runtime: Could not resolve type Document.
[0] {"__symbolic":"error","message":"Could not resolve type","line":50,"character":53,"context":{"typeName":"Document"}}
[0] at \node_modules\@angular\compiler-cli\src\metadata\collector.js:664:27
[0] at Array.forEach (<anonymous>)
[0] at validateMetadata (D:\QPP Workspace\QWC\QWC\node_modules\@angular\compiler-cli\src\metadata\collector.js:652:42)
[0] at MetadataCollector.getMetadata (D:\QPP Workspace\QWC\QWC\node_modules\@angular\compiler-cli\src\metadata\collector.js:507:17)
[0] at LowerMetadataCache.getMetadataAndRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:264:39)
[0] at LowerMetadataCache.ensureMetadataAndRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:209:27)
[0] at LowerMetadataCache.getRequests (ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:204:21)
[0] at ProjectPath\node_modules\@angular\compiler-cli\src\transformers\lower_expressions.js:146:36
[0] at ProjectPath\node_modules\typescript\lib\typescript.js:2601:86
[0] at reduceLeft (ProjectPath\node_modules\typescript\lib\typescript.js:2274:30)
error Command failed with exit code 2.
[0] at ChildProcess.exithandler (child_process.js:275:12)
[0] at emitTwo (events.js:126:13)
[0] at ChildProcess.emit (events.js:214:7)
[0] at maybeClose (internal/child_process.js:925:16)
[0] at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
What is the issue? I am using angular5. And is there any other way to add class dynamically?
You'll get this error if using something like
@Inject(DOCUMENT) document: Document
with your compiler settings in your tsconfig.json set to
"angularCompilerOptions": {
"strictMetadataEmit": true
}
It turns out that the angular compiler doesn't understand the type Document when working out the metadata for injectable parameters, even though it understands the injection token DOCUMENT, and Typescript understands type Document.
This is documented here: https://github.com/angular/angular/issues/20351
The workaround that I use is:
@Injectable({
providedIn: 'root'
})
class MyService {
constructor(@Inject(DOCUMENT) document?: any) {
this._document = document as Document;
}
private _document?: Document;
...
This uses any for the injection signature (making angular happy), but gives you Typescript types within the class.
Note: This is no longer an issue with Ivy on Angular 9 or later. You can just use:
constructor(
@Inject(DOCUMENT) readonly document: Document
) {}
You can add "/** @dynamic */" before your component's decorator:
/** @dynamic */
@Component({
to suppress the error as mentioned here https://github.com/angular/angular/issues/20351#issuecomment-344009887 and here https://angular.io/guide/aot-compiler#strictmetadataemit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With