Here is my base class:
export class DetailsComponent
extends AddClinicComponent
implements OnInit, AfterViewInit{}
in the spec of DetailsComponent.spec
I am tryin to write a testing, which is in AddClinicComponent
component.
here is the test:
fit('it should open popup on click of button add clinic button ', async(() => {
spyOn(component, 'openDialog');
fixture.detectChanges();
const removeButton =
fixture.debugElement.nativeElement.querySelector('.hfs-add-btn');
expect(removeButton).toBeTruthy();
let event = new MouseEvent('click');
removeButton.dispatchEvent(event);
fixture.whenStable().then(() => {
expect(component.openDialog).toHaveBeenCalled();
});
}));
But getting an error as :
Error: Directive AddClinicComponent has no selector, please add it!
how to resolve it?
what is the correct way to test the extended component?
my super class:
import { TemplateRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AddClinicDataService } from '../services/personnel-add-clinic-data.service';
import { HFSClinicTaleSchema } from './hfs-clinic-table.schema';
export abstract class AddClinicComponent {
popTableSchema;
clinicTaleSchema;
@ViewChild('popupTemp', { static: true })
popupTemp: TemplateRef<HTMLAllCollection>;
public primaryName = '';
public primaryAdminId = '';
public dialog: MatDialog;
constructor(protected aAddClinicDataService: AddClinicDataService) {
this.clinicTaleSchema = HFSClinicTaleSchema;
}
clinicRowGenerator(rows) {
return rows.map((p) => {
return {
...p,
address: Object.values(p.address).filter((v) => v != null),
transform: true,
};
});
}
handleAddClinic() {
this.popTableSchema = { ...HFSClinicTaleSchema, rows: [] };
this.openDialog(this.popupTemp);
}
openDialog(templateRef: TemplateRef<HTMLAllCollection>) {
const dialogRef = this.dialog.open(templateRef);
dialogRef.afterClosed().subscribe((result) => {
console.log(`Dialog result: ${result}`);
});
}
addClinics() {
const { rows } = this.popTableSchema;
const transform = [...rows]
.filter((r) => r.checked)
.map((item) => ({ ...item, checked: false }));
if (!transform.length) return;
this.rowTransformer(transform);
this.dialog.closeAll();
}
searchClinics($event: Event): void {
$event.preventDefault();
const formDetails = this.postProfile();
const countryCodes = formDetails.countries.map((v) => v.codeId);
const searchParams = {
primaryAdminId: this.primaryAdminId,
primaryName: this.primaryName,
countryCodes: countryCodes.join(','),
};
this.fetchClinicList(
`name=${this.primaryName}&adminUserName=${
this.primaryAdminId
}&countryCds=${countryCodes.join(',')}`
);
this.primaryAdminId = '';
this.primaryName = '';
}
fetchClinicList(searchParams) {
this.aAddClinicDataService
.getClinicsList(searchParams)
.subscribe((data) => {
const nwRows = data?.map((d) => {
return {
...d,
address: Object.values(d.address).filter(
(v) => v !== null
),
};
});
this.popTableSchema = { ...this.popTableSchema, rows: nwRows };
});
}
protected abstract rowTransformer(value);
abstract postProfile();
}
after having some try: I got this error:
Error: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
constructor of details component:
constructor(
private personnelViewDataService: PersonnelViewDataService,
private personnelTranslateService: PersonnelTranslateService,
private cdr: ChangeDetectorRef,
public dialog: MatDialog,
protected aAddClinicDataService: AddClinicDataService
) {
super();
}
constructor of AddClinicComponent
constructor(protected aAddClinicDataService: AddClinicDataService) {
this.clinicTaleSchema = HFSClinicTaleSchema;
}
CodePudding user response:
Dependency injection works only if the class has an Angular decorator.
DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.
https://angular.io/guide/dependency-injection
This could be causing the error, try to inject the service in the component class and when calling super pass the service to the extended class
constructor of details component:
constructor(
private personnelViewDataService: PersonnelViewDataService,
private personnelTranslateService: PersonnelTranslateService,
private cdr: ChangeDetectorRef,
public dialog: MatDialog,
public aAddClinicDataService: AddClinicDataService
) {
super(aAddClinicDataService);
}