I'm calling a function declared in parent component in the child component in the form of callback.
Parent Component
translation-editor.component.ts
export class TranslationEditorComponent implements OnInit {
textGuid: string = this.actRoute.snapshot.params['textGuid'];
editDataset: any;
currentTopBarConfig: any;
summaryTopbarConfig = [
{
"label": "Save Text",
"function": this.save, //see save function below
},
{
"label": "Delete Text",
"function": this.delete,
}
];
constructor(
private translationService:TranslationService,
public actRoute: ActivatedRoute,
) {
}
ngOnInit(): void {
this.loadDataToEdit();
}
loadDataToEdit(){
this.translationService.getTextById(this.textGuid).subscribe(res => {
this.editDataset = res;
})
this.currentTopBarConfig = this.summaryTopbarConfig;
}
save(){
console.log("this.textGuid",this.textGuid);
if(this.textGuid){
this.translationService.updateText(this.textGuid, this.editDataset).subscribe((res:any)=>{
console.log(res);
});
}
}
delete(){
console.log("delete code lies here");
}
}
translation-editor.component.html
<topbar [config]="currentTopBarConfig"></topbar>
<form [ngClass]="{'hidden':currentTab!=='summary'}" >
<fieldset>
<legend>Field</legend>
<ul *ngIf="editDataset">
<ng-container *ngFor="let key of objectKeys(editDataset)" >
<li *ngIf="key === 'textGuid' || key === 'strongName' || key === 'container'">
<label >
<input type="text" value="{{editDataset[key]}}" readonly>
<span >{{key}}</span>
</label>
</li>
</ng-container>
</ul>
</fieldset>
</form>
I'm calling the save function in the below component as a callback to initiateFunction() function.
Child Component
topbar.component.html
<ul >
<ng-container *ngFor="let btn of config">
<li>
<button
(click)="initiateFunction(btn.function)"
<span >{{btn.label}}</span>
</button>
</li>
</ng-container>
</ul>
topbar.component.ts
export class TopbarComponent implements OnInit {
@Input() config: any[] | undefined;
constructor(private location: Location) { }
ngOnInit(): void {
}
initiateFunction(fnct:any){
fnct();
}
}
Here when function is executed I'm getting an error:
ERROR TypeError: Cannot read properties of undefined (reading 'textGuid')
Where I'm not able access the this.textGuid.
Please give me suggestions on how to solve this.
CodePudding user response:
I think the issue is caused because the save()
function isn't bound to the correct object, so instead you can use Angular component interaction features. You can use @Output
decorator and emit an event that will be handled by parent component.
First, update your TopbarComponent
to add that event:
topbar.component.ts
export class TopbarComponent implements OnInit {
@Input() config: any[] | undefined;
@Output() save: EventEmitter<any> = new EventEmitter();
constructor(private location: Location) {}
ngOnInit(): void {}
onSave() {
this.save.emit();
//fnct();
}
}
topbar.component.html
there was a typo on in button start tag >
<ul >
<ng-container *ngFor="let btn of config">
<li>
<button
(click)="onSave()">
<span >{{btn.label}}</span>
</button>
</li>
</ng-container>
</ul>
Next, update the TranslationEditorComponent
component to bind to that event:
translation-editor.component.html
<topbar [config]="currentTopBarConfig" (save)="save()"></topbar>
You can do the same for other types of events like delete or update. Refer to Angular docs for more details about components interaction and sharing data https://angular.io/guide/inputs-outputs
CodePudding user response:
Your this context has been changed when you call fnct();
. In order to pass the this context to the function you can use javascript bind method.
So you just need to change the config property:
summaryTopbarConfig = [
{
"label": "Save Text",
"function": this.save.bind(this), //bind current context
}
];
Read more about bind: https://www.w3schools.com/js/js_function_bind.asp