When I try to compile the front-end of my project, the following error occurs in the userList.ts
file. Actually, the error occurs in any HTML file located in the ./page
folder, but I will use userList
as an example:
‘error NG8001: ‘mytable’ is not a known element:
If ‘mytable’ is an Angular component, then verify that it is part of this module.
To allow any element, add ‘NO_ERRORS_SCHEMA’ to the ‘@NgModule.schemas’ of this component.’
app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { CollapseModule } from 'ngx-bootstrap/collapse';
import { ModalModule } from 'ngx-bootstrap/modal';
import { TimepickerModule } from 'ngx-bootstrap/timepicker';
import { NgChartsModule } from 'ng2-charts';
import { MyTableModule } from '../../component/myTable/my-table.module';
import { MainPageComponent } from '../app/main/main-page.component';
import { UserListPage } from '../page/userList/userList';
import { NotFoundPage } from '../page/notFound/notFound';
import { SignInPage } from '../page/signIn/signIn';
import { ButtonListPage } from '../page/buttonList/buttonList';
import { EventUtil } from "../util/EventUtil";
import { FileUtil } from "../util/FileUtil";
import { ModalUtil } from "../util/ModalUtil";
import { AppRoutes } from "./app.routes";
import 'chartjs-plugin-datalabels';
@NgModule({
declarations: [
MainPageComponent,
NotFoundPage,
SignInPage,
ButtonListPage,
UserListPage,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
BsDatepickerModule.forRoot(),
CollapseModule.forRoot(),
ModalModule.forRoot(),
TimepickerModule.forRoot(),
NgChartsModule,
AppRoutes,
MyTableModule
],
providers: [
FileUtil,
EventUtil,
ModalUtil,
],
bootstrap: [MainPageComponent]
})
export class AppModule { }
my-table.module.ts :
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyTableComponent } from './myTable.component';
@NgModule({
declarations: [MyTableComponent],
imports: [CommonModule],
exports: [MyTableComponent]
})
export class MyTableModule { }
myTableComponent.ts:
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { User } from '../../model/core/user/User';
export interface MyTableOptions {
hasActions: boolean;
hasSearch: boolean;
hasCreate: boolean;
sortCol?: number;
}
export interface MyTableHeader {
class?: string;
isDate?: boolean;
isCheckbox?: boolean;
sortable?: boolean;
value: string;
}
@Component({
selector: "mytable",
templateUrl: "./myTable.component.html",
styleUrls: ["./myTable.component.scss"]
})
export class MyTableComponent {
@Input() options: MyTableOptions = { hasActions: false, hasSearch: false, hasCreate: false };;
@Input() headers: Array<MyTableHeader> = [];
@Input() rows: Array<User> = [];
@Input() searchCompare: (item: User, value: string) => boolean = () => false;
@Input() sortCompare: (itemA: User, itemB: User, column: number) => number = () => 0;
@Output() onCreate = new EventEmitter<void>();
@Output() onItemsUpdate = new EventEmitter<Array<User>>();
public searchedRows: Array<User> = [];
public sortedRows: Array<User> = [];
public sortCol: number = 0;
constructor() {
}
@Input("options")
set inputSetOptions(options: MyTableOptions) {
this.options = options;
if (options.sortCol) {
this.sortCol = options.sortCol;
this.sortTableCol();
}
}
@Input("headers")
set inputSetHeaders(headers: Array<MyTableHeader>) {
this.headers = headers;
}
@Input("rows")
set inputSetRows(rows: Array<User>) {
this.setRows(rows);
}
@Input("searchCompare")
set inputSetSearchCompare(searchCompare: (item: User, value: string) => boolean) {
this.searchCompare = searchCompare;
}
@Input("sortCompare")
set inputSetSortCompare(sortCompare: (itemA: User, itemB: User, column: number) => number) {
this.sortCompare = sortCompare;
}
public setRows(rows: Array<User>): void {
this.rows = rows;
this.searchedRows = rows;
this.sortedRows = rows;
if (this.sortCol) {
this.sortTableCol();
} else {
for (let i = 0; i < this.headers.length; i++) {
if (this.headers[i].sortable) {
this.sortCol = i + 1;
this.sortTableCol();
break;
}
}
}
}
public update(): void {
this.setRows(this.rows);
}
public onSearch(searchValue: string): void {
this.searchedRows = this.rows.filter(row => this.searchCompare(row, searchValue));
this.sortTableCol();
}
public onPaginate(pageRows: Array<User>): void {
this.onItemsUpdate.emit(pageRows);
}
public toggleSortTableCol(col: number): void {
const fixCol: number = col - 1;
if (!this.headers[fixCol].sortable) {
return;
}
if (this.sortCol === col) {
this.sortCol *= -1;
} else {
this.sortCol = col;
}
this.sortTableCol();
}
public create() {
this.onCreate.emit();
}
public toggleAll(col: number, value: boolean): void {
for (let i = 0; i < this.searchedRows.length; i++) {
this.searchedRows[i][this.headers[col].value.toLowerCase()] = value;
}
}
private sortTableCol(): void {
const fixCol: number = Math.abs(this.sortCol) - 1;
if (!this.headers[fixCol] || !this.headers[fixCol].sortable) {
return;
}
this.sortedRows = this.searchedRows.slice().sort((itemA: User, itemB: User) => {
let sort: number = this.sortCompare(itemA, itemB, fixCol);
if (this.sortCol < 0) {
sort *= -1;
}
return sort;
});
}
}
userList.ts:
import { Title } from "@angular/platform-browser";
import { Component, OnInit } from "@angular/core";
import { ModalUtil } from "../../util/ModalUtil";
import { MyTableOptions, MyTableHeader } from "../../component/myTable/myTable.component";
import { UserService } from "../../service/core/UserService";
import { User } from "../../model/core/user/User";
import { UserCreateResponse } from "../../model/core/user/response/UserCreateResponse";
import { UserEditResponse } from "../../model/core/user/response/UserEditResponse";
import { UserListResponse } from "../../model/core/user/response/UserListResponse";
import { UserCreateModal } from "../../modal/userCreate/userCreate";
import { UserEditModal } from "../../modal/userEdit/userEdit";
@Component({
selector: "userlistpage",
templateUrl: "./userList.html",
styleUrls: ["./userList.scss"]
})
export class UserListPage implements OnInit {
public title: string = "Usuários";
public allItens: Array<User> = new Array();
public itens: Array<User> = new Array();
public tableOptions: MyTableOptions | null = null;
public tableHeaders: Array<MyTableHeader> = new Array();
constructor(
private userService: UserService,
private modalUtil: ModalUtil,
private titleService: Title
) {
}
public async ngOnInit(): Promise<void> {
this.tableOptions = {
hasSearch: true,
hasCreate: true,
hasActions: true
};
this.tableHeaders = [{
value: "Nome",
sortable: true
}, {
value: "E-mail",
sortable: true
}, {
value: "Gestor SESI",
sortable: true
}];
this.updateTitle();
this.getData();
}
public setItens(itens: Array<User>): void {
this.itens = itens;
}
public searchCompare(item: User, value: string): boolean {
const valueLowerCase: string = value.toLowerCase();
const itemValues: Array<string> = [
item.name.toLowerCase(),
item.email.toLowerCase(),
item.root ? "sim" : "nao",
];
for (const itemValue of itemValues) {
if (itemValue.indexOf(valueLowerCase) !== -1) {
return true;
}
}
return false;
}
public sortCompare(itemA: User, itemB: User, column: number): number {
let sortA: boolean = false;
if (column === 0) {
sortA = itemA.name.toLowerCase() > itemB.name.toLowerCase();
} else if (column === 1) {
sortA = itemA.email.toLowerCase() > itemB.email.toLowerCase();
} else if (column === 2) {
sortA = itemA.root > itemB.root;
}
const sort: number = sortA ? 1 : -1;
return sort;
}
public async create(): Promise<void> {
const modal: UserCreateModal = this.modalUtil.showCustom(UserCreateModal, {});
modal.getResult().then((res: UserCreateResponse | null): void => {
if (res !== null) {
this.getData();
}
}).catch((err: Response): void => {
this.modalUtil.showErrorResponse(err).then((): void => {
}).catch((err: Error): void => { });
});
}
public async edit(user: User): Promise<void> {
const modal: UserEditModal = this.modalUtil.showCustom(UserEditModal, {});
modal.init(user);
modal.getResult().then((res: UserEditResponse | null): void => {
if (res !== null) {
this.getData();
}
}).catch((err: Response): void => {
this.modalUtil.showErrorResponse(err).then((): void => {
}).catch((err: Error): void => { });
});
}
public async remove(user: User): Promise<void> {
const title: string = "Remover usuário: " + user.name;
const message: string = "<b>Aviso</b>: Essa ação é irreversível<br><br>Deseja remover o usuário?";
try {
const confirmed: boolean = await this.modalUtil.showConfirm(title, message);
if (!confirmed) {
return;
}
await this.userService.remove(user.id).toPromise();
this.getData();
} catch (err) {
this.modalUtil.showErrorResponse(err).then((): void => {
}).catch((err: Error) => { });
}
}
public hasPermission(user: User): boolean {
const userId: number = Number(localStorage.getItem("userId"));
return user.id !== userId;
}
private updateTitle(): void {
this.titleService.setTitle(this.title);
}
private async getData(): Promise<void> {
try {
const res: UserListResponse | undefined = await this.userService.list().toPromise();
if (res) {
const newItens: Array<User> = [];
for (const user of res.users) {
if (user.active) {
newItens.push(user);
}
}
this.updateTitle();
this.allItens = newItens;
} else {
console.error('UserListResponse is undefined');
}
} catch (err) {
this.modalUtil.showErrorResponse(err).then(() => {
}).catch((err: Error) => { });
}
}
}
userList.html :
<div class="my-page-header">
<span class="title">{{title}}</span>
</div>
<div class="my-page-content">
<mytable [headers]="tableHeaders" [options]="tableOptions" [rows]="allItens" [searchCompare]="searchCompare"
[sortCompare]="sortCompare" (onItensUpdate)="setItens($event)" (onCreate)="create()">
<tr *ngFor="let item of itens; let i = index">
<td [innerHTML]="item.name"></td>
<td [innerHTML]="item.email"></td>
<td>
<span *ngIf="item.root">Sim</span>
<span *ngIf="!item.root">Não</span>
</td>
<td class="text-right">
<button *ngIf="hasPermission(item)" type="button" class="btn btn-warning" title="Editar usuário"
(click)="edit(item)">
<span class="glyphicon glyphicon-edit"></span>
</button>
<button *ngIf="hasPermission(item)" type="button" class="btn btn-danger" title="Remover usuário"
(click)="remove(item)">
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
</mytable>
</div>
I have already tried importing the MyTableComponent directly in app.module.ts, but the same error occurs.
Versions:
Angular CLI: 17.3.8
Node: 18.13.0
Package Manager: npm 8.19.3
OS: linux x64
Angular: 17.3.12
rxjs 6.6.7
typescript 5.4.5
zone.js 0.14.8
After running the ng build command, it should create the dist folder, but with the error, the project does not compile.
The project is running in a Docker container on a remote Linux server.
I already tried the CUSTOM_ELEMENTS_SCHEMA and NO_ERRORS_SCHEMA
Gabriela Zanon dos Santos is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.