0

Hi I can't pass my data from child to parent using @ViewChild

I have this code from

admin-layout.component.ts

@ViewChild(TribeComponent)
 getRoute :TribeComponent; 

ngAfterViewInit() {
  console.log( this.getRoute);
  this.message = this.getRoute.messagetwo;
  console.log('Values on ngAfterViewInit():');
  console.log("primaryColorSample:", this.message);
}  

and code from

tribecomponent.ts

messagetwo:string = "true";

the error is

TypeError: Cannot read property 'messagetwo' of undefined
at AdminLayoutComponent.push../src/app/layouts/admin-layout/admin-layout.component.ts.AdminLayoutComponent.ngAfterViewInit (admin-layout.component.ts:45)
at callProviderLifecycles (core.js:22416)
at callElementProvidersLifecycles (core.js:22390)
at callLifecycleHooksChildrenFirst (core.js:22380)
at checkAndUpdateView (core.js:23316)
at callViewAction (core.js:23548)
at execEmbeddedViewsAction (core.js:23511)
at checkAndUpdateView (core.js:23308)
at callViewAction (core.js:23548)
at execComponentViewsAction (core.js:23490)

the first console was undefined console.log( this.getRoute);

the second one was the error above console.log("primaryColorSample:", this.message);

btw admin-layout is kind of my app component html so I use router outlet to navigate to tribe component. Is it the reason why it can't see tribe as its child? here's a sample how my layout work Creative Tim's Argon Dashboard Angular

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
Mark
  • 293
  • 1
  • 11
  • 25
  • Do you have any `*ngIf` in your template above the child you are querying? – Reactgular Jul 08 '19 at 08:54
  • no I don't have @Reactgular – Mark Jul 08 '19 at 09:15
  • Does your template have `` because you need to use `@ContentChild` instead for that. – Reactgular Jul 08 '19 at 09:24
  • @Reactgular how do I use it? – Mark Jul 08 '19 at 14:06
  • i investigated your project structure and [admin-layout.component](https://github.com/creativetimofficial/argon-dashboard-angular/blob/master/src/app/layouts/admin-layout/admin-layout.component.html) doesn't have `TribeComponent` neither as ViewChild nor as ContentChild. It is placed under router-outlet and it becomes a child of `admin-layout.component` in DOM tree not in Angular's View Hierarchy. There is a [discussion](https://github.com/angular/angular/issues/14842) about this. And there is a good explanation [here](https://github.com/angular/angular/issues/14842#issuecomment-470167258) – ysf Jul 08 '19 at 19:12
  • since those two component doesn't have a direct parent/child relationship. you cannot use Input/Output mechanics or View/Content queries. you need a broker service to share data. see [this post](https://stackoverflow.com/questions/44414226/angular-4-pass-data-between-2-not-related-components) on how you can do it. – ysf Jul 08 '19 at 19:16
  • @ysf you should've answered it I found the solution thanks! – Mark Jul 09 '19 at 05:34

1 Answers1

0

To send data from child to parent use events (not ViewChild) - e.g in child:

@Output() public myevent = new EventEmitter<any>();

...
fireEvent() {
  this.myevent.emit({'some':'data'});
}

and in parent template

<child-component (myevent)="handleEvent($event)">...</child-component>

where handleEvent(data) is your pratent function which will get emited data from child

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345