Home > Mobile >  Correct way to pass data from parent to grandchild in Angular. Is that correct?
Correct way to pass data from parent to grandchild in Angular. Is that correct?

Time:01-25

I'm trying to pass data from parent component to a child component. I have somthing like that:

Parent component:

@Component({
  selector: 'foo-parent',
  templateUrl: './foo-parent.component.html',
  styleUrls: ['./foo-parent.component.scss'],
})
export class FooParent {

  @Input() data: any;

  constructor() { }

}

The parent receives the data from another library where all the logic is executed.

Grandchild component:

@Component({
  selector: 'foo-grand-child',
  templateUrl: './foo-grand-child.component.html',
  styleUrls: ['./foo-grand-child.component.sass'],
})

export class FooGrandChild {

  data: any;

  constructor(private fooParent: FooParent) {
    this.data = this.fooParent.fooGrandChildData;
   }

This way works correctly but I'm a newbie and I don't know if it's the right way to do it. Is there another way to do it other than bridging the parent > child > grandchild component?

CodePudding user response:

I don't think that is the Angular way to communicate data between your components. As you already know the relationship between your components (which is good), You can pick the right method of communication between your components.

I suggest reading https://fireship.io/lessons/sharing-data-between-angular-components-four-methods/

As for your use case. Parent to Grand Children.

I suggest using a Service, that's set the field/property by your Parent Component and then your Grandchild Component gets that field/property, instead of directly Injecting the Parent Component in your Grandchild Component

Parent Component

@Component({
  selector: 'foo-parent',
  templateUrl: './foo-parent.component.html',
  styleUrls: ['./foo-parent.component.scss'],
})
export class FooParent implements OnInit {

  constructor(private sharedtestService: SharedTestService) { }
  
  ngOnInit(): void {
      this.sharedtestService.setTestData('string');
  }    
}

Grandchild Component

@Component({
  selector: 'foo-grand-child',
  templateUrl: './foo-grand-child.component.html',
  styleUrls: ['./foo-grand-child.component.sass'],
})

export class FooGrandChild implements OnInit {

  data: string;

  constructor(private sharedtestService: SharedTestService) {}

  ngOnInit(): void {
     this.data = this.sharedtestService.getTestData();
  }
 }

Shared Service

@Injectable({
  providedIn: 'root'
})
export class SharedTestService {
  testData: string;
  constructor() {}

  setTestData(temp: string): void {
    return this.testData = temp;
  }

  getTestData(): string {
    return this.testData;
  }
}

I also suggest looking into Observablesand how to subscribe to them, if you want your GrandChildren Component to automatically listen to changes that are done by your Parent Component.

CodePudding user response:

Several things, first of all if you want to pass something from a parent to a child and from this to its child (the grandchild of the parent component) in the children (where you receive the data) we use the @Input() decorator not in the parent. @Input() data is in @output() data is out. This is why @Input() should be used on child components. Once you have the @Input in the child component you can pass the value to that variable through the HTML. I show you an example:

Child (ts):

@Component({
    selector: 'child-sample-component',
    templateUrl: './child-sample-component.component.html',
})

export class ChildSampleComponenet {
    @Input() childObject;
}

Parent (html):

 <child-sample-component [childObject]="parentObject">

 </child-sample-component>

Notice how in the child we have the @Input with the childObject variable and in the parent html we give the value to childObject with the parentObject parent variable that will contain whatever.

There are other ways as well such as using services etc. But you should learn that as you go. Here are a couple of interesting links.

https://angular.io/guide/inputs-outputs

https://angular.io/guide/architecture-services

  •  Tags:  
  • Related