0

I have 2 component parent (Login Screen) and a child (user-list). Parent component has dropdowlist. The grid loads according to the item chosen in the drop down list I need to fire function of the child component and this is not working for me. I have the following code: parent component html:

I have the following code:

 <div>[items]="UserTypeSelectItems"[(ngModel)]="UserTypeId" id="fieldType"
 bindLabel="value" bindKey="key" (change)="changeUserType()" [clearable]="false">
 </div>
 <app-user-list></app-user-list>

parent component ts:

I have the following code:

export class Login-ScreenComponent implements OnInit {
@ViewChild(UserListComponent)child:UserListComponent;
userTypeSelectItems: Array<SelectItem>;
userTypeId: any;
items: any;
constructor(    
private userTypeSettingsService: userTypeSettingsService,

) {
this.userTypeSettingsService.getuserTypes().subscribe((data) => {
  this.userTypeSelectItems = data;
  if (
    this.userTypeSelectItems &&
    this.userTypeSelectItems.length > 0
  ) {
    this.userTypeId =
      this.userTypeSettingsService.selectedContractTypeId ??
      this.userTypeSelectItems[0].key;
    this.userTypeSettingsService.setContractTypeId(this.contractTypeId);
    this.userTypeSettingsService.fillSelectedFields(this.userTypeId).subscribe(dataFields => {
      this.items = dataFields;
      this.child.getUser();
       });
      }
      });
       }
      changeUserType() {
      this.child.getUser();
       }

child component ts:

I have the following code:

getUser() {
this.loading = true;
this.userService
  .getAllUsers(this.userTypeId)
  .pipe(finalize(() => (this.loading = false)))
  .subscribe(
    (data) => {
      this.rows = data.map(notif => {
        return {
          user_status_id: status_id,     
      });
    },
    (err) => this.toastr.error(err),
    () => (this.loading = false)
  );

} '''''''

salma
  • 41
  • 1
  • 8
  • Does this answer your question? [Call child component method from parent class - Angular](https://stackoverflow.com/questions/38974896/call-child-component-method-from-parent-class-angular) – Leonel Thiesen Nov 23 '22 at 17:28

1 Answers1

0

if I understand your question correctly, that's what I'd suggest

Parent HTML

<div>[items]="UserTypeSelectItems"[(ngModel)]="UserTypeId" id="fieldType"
 bindLabel="value" bindKey="key" (change)="changeUserType()" [clearable]="false">
 </div>
 <app-user-list [userTypeId]="userTypeId"></app-user-list>

In the parent ts remove all the calls of the this.child.getUser()

In the child component you should have input parameter userTypeId with setter. It will invoke the getUser() function every time when value is changed.

private _userTypeId: number;
@Input() 
get userTypeId(): number {
  return this._userTypeId;
}
set userTypeId(value: number): void {
  this._userTypeId = value;
  this.getUser();
}

You also can use the external service which will be injected in the parent and child components or use some Subject in the parent component, create Observable base of it which will be sent as input parameter to the child component. There you subscribe on the observable and then you need to emit the value with subjectvar.next(value) and as result function will be called. I can write down the example if you need.

UPD: example with observables

Parent component ts file:

private userTypeIdSubject$ = new Subject<string>();
private userTypeId$ = this.userTypeIdSubject$.asObservable();

changeUserType(): void {
  // some code goes here
  this.userTypIdSubject$.next(userTypeId); // this should send the message to the observer (child)
}

Parent HTML:

<div>[items]="UserTypeSelectItems"[(ngModel)]="UserTypeId" id="fieldType"
 bindLabel="value" bindKey="key" (change)="changeUserType()" [clearable]="false">
 </div>
 <app-user-list [userTypeObservable]="userTypeId$"></app-user-list>

Child TS

@Input() 
userTypeObservable: Observable<string>;

ngOnInit() {
  if(this.userTypeObservable) {
    this.userTypeObservable.subscribe(
      (userTypeId) => {
        this.userTypeId = userTypeId;
        this.getUser();
      }
    }
  }
}
Alexey Zelenin
  • 710
  • 4
  • 10