Home > database >  Parent to child using ngFor to pass on click
Parent to child using ngFor to pass on click

Time:01-23

load-view.component.ts is the parent file that has a method

    anyData: any;
    pushLoadLocationData(Id: number) {
        this.anyData = Id;
        console.log(Id); //shows data
        this.currentSubjectLocationView.subscribe((data: any) => {
          this.anyData= data.filter(d => d.id === Id)[0].locations;
        });
      }    

to push data through anyData into this page load-view.component.html as parent to child like this [locationData]="anyData"

<tr *ngFor="let loadData of customerLoadAndLocation;let i = index">
   <td >{{i 1}}<br />
      Mile {{i}}<br />
   </td>
   <td >
      <b>XYZ Transportation</b>                                                
      <a href="" data-toggle="modal" data-target="#StopsDetailspop">
        <i (click)="pushLoadLocationData(loadData.id)">
        </i>
      </a>
      <!-- Modal-->
      <div  id="StopsDetailspop" tabindex="-1"
         role="dialog" aria-labelledby="StopsDetailspop" aria-hidden="true">                                                    
         <app-update-location-of-add-stop [locationData]="anyData"></app-update-location-of-add-stop>
      </div>
   </td>
</tr>

At the receiving child page is this.

@Input() locationData: any;
constructor() { }

  ngOnInit(): void {
    console.log(this.locationData); // shows undefined
}

So the click button pushLoadLocationData does not work to send data from parent to child within this *ngFor loop as sure it gives undefined on child page due to the fact that locationData is having no data but on click the data is not able to reach to this child page.

CodePudding user response:

If I understood your question right, the problem is, that anyData doesn't contain your expected data yet, when the HTML-Template gets rendered.

I'd recommend subscribing to currentSubjectLocationView in the HTML-Template by making use of the async pipe:

<tr *ngFor="let loadData of customerLoadAndLocation;let i = index">
   <td >{{i 1}}<br />
      Mile {{i}}<br />
   </td>
   <td >
      <b>XYZ Transportation</b>                                                
      <a href="" data-toggle="modal" data-target="#StopsDetailspop">
        <i (click)="pushLoadLocationData(loadData.id)">
        </i>
      </a>
      <!-- Modal-->
      <div *ngIf="locationData$ | async as locationData"  id="StopsDetailspop" tabindex="-1"
         role="dialog" aria-labelledby="StopsDetailspop" aria-hidden="true">                                                    
         <app-update-location-of-add-stop [locationData]="locationData"></app-update-location-of-add-stop>
      </div>
   </td>
</tr>

Your typescript code of load-view component would then look like:

locationData$: Observable<any>;
pushLoadLocationData(id: number) {
    locationData$ = this.currentSubjectLocationView.pipe(
        filter((x) => x.id === id),
        map((x) => x[0].locations)
    );
}

Note that you have to import Observable, filter and map operator from rxjs

CodePudding user response:

actully the data not ready before click on the i element if you want to get the data based when it ready just you have to follow this approach
you can change the child component input to be setter like this

import {Subject} from 'rxjs';

// the child component 
// ...


private _clickedData = new Subject<any>();

@Input() set locationData(value: any) {this._clickedData.next(value)}

constructor() { }

  ngOnInit(): void {
   this._clickedData.subscribe((value: any)=>{
      console.log(value) // you will get the data when it changed by clicked from the parent Component 
   })
 }
  • Related