preprocess: ERROR could not parse #Component() metadata path/to/my.component.ts - javascript

I have updated my angular project to Angular v11 which successfully updated. This brought a warning that TSLint is deprecated and following the steps outlined Here - Migrating from Codelyzer and TSLint I managed to migrate this.
After this update, I received several errors which I have an idea of how to solve, except this one error
Error: Debug Failure. False expression: position cannot precede the beginning of the file
at computeLineOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8934:22)
at computeLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8912:26)
at Object.getLineAndCharacterOfPosition C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8953:16)
at SourceFileObject.getLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:143309:23)
at preprocess (C:\Path\to\Project\node_modules\#angular-eslint\eslint-plugin-template\dist\index.js:1:1430)
at Linter._verifyWithProcessor (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1292:30)
at Linter._verifyWithConfigArray (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1264:25)
at Linter.verify (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1226:25)
at Linter.verifyAndFix (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1416:29)
at verifyText (C:\Path\to\Project\node_modules\eslint\lib\cli-engine\cli-engine.js:239:48)
preprocess: ERROR could not parse #Component() metadata C:\Path\to\Project\src\app\components\label-star-required\label-star-required.component.ts
Error: Debug Failure. False expression: position cannot precede the beginning of the file
at computeLineOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8934:22)
at computeLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8912:26)
at Object.getLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:8953:16)
at SourceFileObject.getLineAndCharacterOfPosition (C:\Path\to\Project\node_modules\typescript\lib\typescript.js:143309:23)
at preprocess (C:\Path\to\Project\node_modules\#angular-eslint\eslint-plugin-template\dist\index.js:1:1430)
at Linter._verifyWithProcessor (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1292:30)
at Linter._verifyWithConfigArray (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1264:25)
at Linter.verify (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1226:25)
at Linter.verifyAndFix (C:\Path\to\Project\node_modules\eslint\lib\linter\linter.js:1416:29)
at verifyText (C:\Path\to\Project\node_modules\eslint\lib\cli-engine\cli-engine.js:239:48)
preprocess: ERROR could not parse #Component() metadata C:\Path\to\Project\src\app\components\skip-link\skip-link.component.ts
Below are the two components throwing this error
label-star-required.component.ts
import {Component} from '#angular/core';
#Component({
selector: 'app-label-star-required',
templateUrl: './label-star-required.component.html',
styleUrls: ['./label-star-required.component.css']
})
export class LabelStarRequiredComponent {
constructor() {
}
}
#Component({
selector: 'app-star-required',
template: `
<span class='icon-star required'></span>
`,
styleUrls: ['./label-star-required.component.css']
})
export class StarRequiredComponent {
constructor() {
}
}
skip-link.component.ts
import { Component, OnInit, OnDestroy } from '#angular/core';
import { Router, NavigationStart } from '#angular/router';
import { filter, takeWhile, map } from 'rxjs/operators';
#Component({
selector: 'app-skip-link',
styleUrls: ['./skip-link.component.css'],
template: `
<a [href]="skipLinkPath" class="skip-main">Skip to main content</a>
`
})
export class SkipLinkComponent implements OnInit, OnDestroy {
skipLinkPath: string;
componentIsActive: boolean;
constructor(
private router: Router
) { }
ngOnInit() {
this.componentIsActive = true;
this.skipLinkPath = `${this.router.url.replace('#main', '')}#main`;
this.router.events.pipe(filter(event => event instanceof NavigationStart))
.pipe(takeWhile(() => this.componentIsActive))
.pipe(map(event => (event as any).url ))
.subscribe(url => {
if (!/(.)#main$/.test(url)) {
this.skipLinkPath = `${url}#main`;
}
});
}
ngOnDestroy() {
this.componentIsActive = false;
}
}
From the above two components, I can see that the common similarity is that both the files are using
inline template: . Might this be causing the error while running ng lint ? How do I solve this?

My workaround was to move the html code in the component template to templateUrl.
#Component({
selector: 'app-star-required',
template: `<span class='icon-star required'></span>`,
styleUrls: ['./label-star-required.component.css']
})
Becomes
#Component({
selector: 'app-star-required',
templateUrl: './label-star-required.component.html',
styleUrls: ['./label-star-required.component.css']
})

Seems to be a bug with ESlint/Angular configuration.
As a workaround, i added "endOfLine": "lf" to my prettier config which fixed the issue after reformatting the project.
See https://github.com/angular-eslint/angular-eslint/issues/185

I noticed this error too with templates that had escaped double quotes in them:
template: "<div class=\"my-class\"></div><ng-content></ng-content>"
I solved it by switching to single quotes:
template: "<div class='my-class'></div><ng-content></ng-content>"

Related

Can't resolve all parameters for HomeInnerComponent Angular 7

I'm getting the below error in my console when trying to run my Angular application. Here is my html code if you need it https://stackblitz.com/edit/angular-xrbrjq?file=src%2Fapp%2Fapp.component.html
Error: Can't resolve all parameters for HomeInnerComponent: (?).
Please have a look below for my component details.
Home-inner.component.ts:
import { Component, OnInit } from '#angular/core';
import {CategoriesService } from '../../Admin/categories/categories.service';
import {Categories } from '../../Admin/categories/categories';
#Component({
selector: 'app-home-inner',
templateUrl: './home-inner.component.html',
styleUrls: ['./home-inner.component.css']
})
export class HomeInnerComponent implements OnInit {
leftCat:Categories;
constructor(private leftCategoriesService: CategoriesService) { }
ngOnInit() {
// For showing category list in the left side
this.leftCategoriesService.getCategories()
.subscribe((data: any) => {
this.leftCat = data;
//console.log(this.leftCat);
// localStorage.removeItem('editEmpId');
});
// Left side category list ends here
}
}

How to define JitsiMeetExternalAPI in angular 8

I'm using jisti application to implement video call in angular 8,am not understanding JitsiMeetExternalAPI how to define this. please help me on this.(Am getting error as error TS2304: Cannot find name 'JitsiMeetExternalAPI'.).
Simply add this line to app.component.ts.
declare var JitsiMeetExternalAPI: any;
In my case, it worked fine.
Finally, the code looks like this.
import { Component, AfterViewInit } from '#angular/core';
import '../vendor/jitsi/external_api.js';
declare var JitsiMeetExternalAPI: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'sidenav';
domain: string = "meet.jit.si";
options: any;
api: any;
constructor() {
}
ngAfterViewInit(): void {
this.options = {
roomName: "JitsiMeetAPIExample",
width: 700,
height: 700,
parentNode: document.querySelector('#meet')
}
this.api = new JitsiMeetExternalAPI(this.domain, this.options);
}
}
I was facing the same issue and solved by pointing to the script in angular.json like the following ...
"scripts": ["src/vendor/jitsi/external_api.js"]
I had to download and copy the https://meet.jit.si/external_api.js script onto "src/vendor/jitsi" directory of my angular code.

Angular Portal cdkPortal directive throw Expression Changed error

I use Angular Material Portal to move element in another place.
I use cdkPortal and cdkPortalOutlet.
I don't understand why angular throw expression changed in this super simple example
import { Component, ViewChild } from '#angular/core';
import { CdkPortal } from '#angular/cdk/portal';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
#ViewChild(CdkPortal, { static: false }) portal: CdkPortal
}
Check code here:
https://stackblitz.com/edit/angular-f6sb21
open console to see error:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'portal: undefined'. Current value: 'portal: [object Object]'
You are referencing the same object to the cdkPortalOutlet. You actually need another ng-template with its ViewChild
<ng-template #templatePortalContent>Hello, this is a template portal</ng-template>
and in the ts file:
// This is the reference for the ng-template that we added
#ViewChild("templatePortalContent", { static: false }) templatePortalContent: TemplateRef<any>;
// This is the variable that will hold the new template
templatePortal;
constructor(private _viewContainerRef: ViewContainerRef, private cdr: ChangeDetectorRef) {}
ngAfterViewInit() {
this.templatePortal = new TemplatePortal(
this.templatePortalContent,
this._viewContainerRef
);
this.cdr.detectChanges();
}
This is for the TemplatePortal.
If you need a ComponentPortal, it means if you have already a component, then you will need to create the portal and assign it in the cdkPortalOutlet instead of templatePortal variable.
this.componentPortal = new ComponentPortal(ComponentPortalExample);
and
<ng-template [cdkPortalOutlet]="componentPortal"></ng-template>
You can check here for more info:
Here is the demo.

Integrate xterm.js to Angular

I'm new to Angular.
I'm trying to use xterm.js (https://xtermjs.org/) but it display badly.
Here is the render :
Render
I created a xterm component. The xterm.component.ts file code is :
import { Component, OnInit } from '#angular/core';
import { Terminal } from "xterm";
#Component({
selector: 'app-xterm',
templateUrl: './xterm.component.html',
styleUrls: ['./xterm.component.css'],
})
export class XtermComponent implements OnInit {
public term: Terminal;
container: HTMLElement;
constructor() { }
ngOnInit() {
this.term = new Terminal();
this.container = document.getElementById('terminal');
this.term.open(this.container);
this.term.writeln('Welcome to xterm.js');
}
}
My xterm.component.html only contains this :
<div id="terminal"></div>
I don't really know what to do more ...
Thanks in advance guys
You must set the component encapsulation
#Component({
encapsulation: ViewEncapsulation.None,
...
})
Encountered the same problem and found this page.
Maybe this is too late for the OP, but could be useful for others.
The styles are wrong because 1) the xterm.css is not loaded, and 2) the encapsulation.
My solution to 1) was to add #import 'xterm/dist/xterm.css'; in the scss file for this component.
And 2) can be solved by setting encapsulation: ViewEncapsulation.None as Victor96's answer, or better setting encapsulation: ViewEncapsulation.ShadowDom.
Hope this helps.
I know this is old, but I had to put terminal initialation in ngAfterViewInit. Otherwise the DOM elements are undefined.
Try to use in template reference variable by using the hash symbol
<div #myTerminal></div>
and in component
#ViewChild('myTerminal') terminalDiv: ElementRef;
In ngOnInit
ngOnInit() {
this.term = new Terminal();
this.term.open(this.terminalDiv.nativeElement);
this.term.writeln('Welcome to xterm.js');
}

Why does #Output create circular json error?

Trying to catch an event emitted from my quantity-component
When I take away the #Output decorator everything works fine, but when I include it to catch the event I get this error:
EXCEPTION: Error in ./QuantityComponent class
QuantityComponent - inline template:0:567 caused by: Converting
circular structure to JSONErrorHandler.handleError #
...
ORIGINAL EXCEPTION: Converting
circular structure to JSON
What am I doing wrong?
// item-component.ts
import {Component, Input, Output, EventEmitter} from '#angular/core';
#Component({
selector: 'item-component',
template: '<quantity-component [initialQuantity]="initialQuantity" (change)="myValueChange($event)" ></quantity-component>'
})
export class ItemComponent {
myValueChange($event){
console.log($event);
}
}
// quantity-component.ts
import {Component, Input, Output, EventEmitter} from '#angular/core';
#Component({
selector: 'quantity-component',
templateUrl: 'quantity.component.html'
})
export class QuantityComponent {
#Input() item: string;
#Input('initialQuantity') counterValue = 0;
#Output('change') counterChange: EventEmitter<any> = new EventEmitter();
increase() {
this.counterValue++;
this.counterChange.emit({
value: this.counterValue
})
}
decrease() {
this.counterValue--;
this.counterChange.emit({
value: this.counterValue
})
}
}

Categories