0
votes

I have parent and child component communication, I want to fire up a method in child component that should open up a modal and pass the data. When I call a function from parent using ViewChild, the variable in the child method component returns null, however should have data inside variable. When I fire same function within the child component, the data is available, but its not a case when called from parent component. What is missing and why I don't see data in child component, from fire up from the parent component?

parent.html

    <button (click)="openModal()">New</button>

    <child><child>

parent.ts

    import { FilterComponent } from './../filter/filter.component';

    @ViewChild(FilterComponent) filterComponent: FilterComponent;


    openModal(){
       this.filterComponent.openModal(); // when fired from here, the function in the child component fires, but the variable inside it returns null
    } 

child.html

       <button (click)="openModal()">New</button>
       <modal><modal>

child.ts

     openModal(){
       modalVisible = true;
        console.log(this.filter) returns null; when fired from parent component 
        console.log(this.filter) returns "filter data"; when fired within the component
      }
3
I appreciate the added code, but I'm afraid it's not enough to determine whats wrong. Can you please share enough code to reproduce the problem? Preferably with a StackBlitz example. - Silvermind
When you using viewchild within your parents it does not initialize the child components .. in simple word it doesn't called it's constructor.. you can confirm with afterviewchild lifecycle in parent component ... And you using this.filter in child component which is not intialized.. these this the problem statement in code... It will be always be null.. if you that want value u must initialize from parent component - abhijeet abanave

3 Answers

2
votes

From what I can tell you are currently selecting ALL FilterComponents inside your parentComponent. In order to use this you need to be more specific. You can change your ViewChild to select only one FilterComponent if that fits your use case.

Example:

parent.html

<button (click)="openModal()">New</button>

<!-- notice the #child attribute -->
<child #child><child>

Then in parent.component.ts

import { FilterComponent } from './../filter/filter.component';

@ViewChild("child") filterComponent: FilterComponent;


openModal(){
   this.filterComponent.openModal(); // now that you're only selecting one element this function call should have access to this values. 
} 

You can also reference the relevant stack blitz i made here: https://stackblitz.com/edit/angular-lqmc8x

Good luck!

0
votes

I think you need an EventEmitter.

parent.html <child (messageEvent)="openModal($event)"></child>

child.ts import { Component, Output, EventEmitter } from @angular/core; export class... @Output() messageEvent = new EventEmitter<string>(); openModal(val) { this.messageEvent.emit(val); }

child.html <button (click)="openModal(val)">Click</button>

or something like that.

0
votes

I think you should rethink your architecture here.

If the method is triggered from the parent component only, then put into the parent component

If the the method is triggered from both parent AND child component, then put into a service