0

I am facing a problem with updating a child component without reloading the whole site.

the structure parent component is:

parent component:

<div class="overview">
  <div class="vehicle-img">
    <img src={{vehicleImg}} />
  </div>
  <div class="board">
    <div class="board-column company-overview">
      <div class="board-column-header">{{ "COMPANY_OVERVIEW.TITLE" | translate}}</div>
      <div class="board-column-content">
        <app-company-overview [companyOverviewData]="companyOverviewData"></app-company-overview>
        <div *ngIf="!companyOverviewData" class="loading">
          <app-loading></app-loading>
        </div>
      </div>
    </div>
    <div class="board-column feeds">
      <div class="board-column-header">{{ "FEEDS.TITLE" | translate}}</div>
      <div class="board-column-content">
        <app-feeds [FeedsData]="feedsData"></app-feeds>
        <div *ngIf="!feedsData" class="loading">
            <app-loading></app-loading>
      </div>
    </div>
  </div>
</div>

the feeds component :


<div class="feeds">
  <mat-card class="feed-card">
    <mat-card-title>
      <div class="title">
        <h3>{{ 'FEEDS.SUBTITLE' | translate}} {{vin}}</h3>
        <hr>
      </div>
    </mat-card-title>
    <app-feed-list></app-feed-list>
    <div class="comment">
      <textarea class="textarea" matInput placeholder="Enter your comment ..." [(ngModel)]="feedsComment"></textarea>
      <button mat-button [disabled]="!feedsComment" (click)="sendComment()">
        <mat-icon class="send-button" matSuffix>send</mat-icon>
      </button>
    </div>
  </mat-card>
</div>

in this component,there is a input field and a button. if the button is clicked, it will call the post api service. to send the data to Backend.

public sendComment(): void {
    alert(this.feedsComment);
    let newFeeds = this.createFeeds();
    this.feedsService.sendFeedsComment(newFeeds).subscribe(() => {
      this.feedsService.getFeedsOverview(this.vin).subscribe((feedsData: Feeds[]) => {
        this.feedsOverviewData = feedsData;
      });
    });
  }

feeds-list.html:

<div class="feed-list">
  <table mat-table [dataSource]="dataSource">
    <ng-container matColumnDef="feeds">
      <td mat-cell *matCellDef="let item">
        <mat-card-header>
          <div mat-card-avatar>
            <mat-icon class="avatar">insert_emoticon</mat-icon>
          </div>
          <mat-card-title class="feeds-header"><b>
              <div *ngIf="item.comment !== ''">
                <span>n-Level {{item.user}}</span>
              </div>
              <div *ngIf="item.comment === ''">
                <span>Event</span>
              </div>
            </b>
          </mat-card-title>
          <mat-card-subtitle class="feeds-date">{{item.date | date: 'dd/MM/yyyy'}}</mat-card-subtitle>
        </mat-card-header>
        <mat-card-content>
          <div *ngIf="item.comment !== ''">
            <div class="feeds-info">{{item.comment}}</div>
          </div>
          <div *ngIf="item.comment === ''">
            <div class="feeds-info">FIN search executed by {{item.user}}.</div>
          </div>
        </mat-card-content>
      </td>
    </ng-container>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>
  <div class="footer">
    <mat-paginator [length]="" [pageSize]="5" [pageSizeOptions]="[5, 10, 20, 30, 40, 50]" showFirstLastButtons></mat-paginator>
  </div>
</div>

and feeds-list.ts

export class FeedListComponent implements OnInit {
  displayedColumns: string[] = ['feeds'];
  @Input() feedsOverviewData: Feeds[];
  @ViewChild(MatPaginator) paginator: MatPaginator;
  dataSource = new MatTableDataSource<Feeds>(DATA);
  constructor() {
  }

I this feeds component, it has also a child component feed-list component

my qustion is, if the call sendFeedsComment returns 200 back, it should this new comments be shown in the feed-list without uploading the whole site.

I have a idea, I can call the api getAllFeeds to get all comments, but this api will be used in the parent component.

what is the right way to implement

can somebody help me?

Best Regards,

Leo

user1938143
  • 1,022
  • 2
  • 22
  • 46
  • What is 'feedsData' for parent component here which is you are passing here in app-feeds component as property binding ? It is not making sense.And here in your case you simply need to pass the data you are getting here i.e. feedsOverviewData as a property binding to your 'app-feed-list' component.After doing this it will automatically run ngOnchanges life cycle for 'app-feed-list' whenever api get called and that Input property changes then you will have updated data with no page reload. – Nirali Mar 29 '19 at 05:53

1 Answers1

1

All you need is ngOnChanges on feeds-list.ts, ngOnchanges trigger when ever the input param value is change so in your case your input param is feedsOverviewData. here is the example. i hope it helps you out

feeds.html

   <div class="feeds">
     <mat-card class="feed-card">
      <mat-card-title>
         <div class="title">
            <h3>{{ 'FEEDS.SUBTITLE' | translate}} {{vin}}</h3>
            <hr>
         </div>
     </mat-card-title>
     <app-feed-list  [feedsOverviewData]="feedsOverviewData"></app-feed-list>
     <div class="comment">
       <textarea class="textarea" matInput placeholder="Enter your comment ..." 
          [(ngModel)]="feedsComment"></textarea>
       <button mat-button [disabled]="!feedsComment" (click)="sendComment()">
       <mat-icon class="send-button" matSuffix>send</mat-icon>
     </button>
     </div>
     </mat-card>
     </div>

feeds.ts

   public sendComment(): void {
      alert(this.feedsComment);
    let newFeeds = this.createFeeds();
    this.feedsService.sendFeedsComment(newFeeds).subscribe(() => {
       this.feedsService.getFeedsOverview(this.vin).subscribe((feedsData: Feeds[]) => 
     {
       this.feedsOverviewData = feedsData;
     });
    });
  }

feeds-list.ts

   import { OnChanges, SimpleChanges } from '@angular/core';

   export class FeedListComponent implements OnInit, OnChanges {
   displayedColumns: string[] = ['feeds'];
   @Input() feedsOverviewData: Feeds[];
   @ViewChild(MatPaginator) paginator: MatPaginator;
   dataSource = new MatTableDataSource<Feeds>(DATA);

   constructor() {
   }

    ngOnChanges(changes: SimpleChanges): void {
    if (changes != null) {
         console.log(changes);
            // here you will get the updated data when ever you click the sendComment button on feeds 
     }
    }
Yash Rami
  • 2,276
  • 1
  • 10
  • 16
  • the problem, How can I bind dataSource with dynamic data ? – user1938143 Mar 29 '19 at 12:40
  • can you show me the log of the changes? bcs on changes you will get the updated data so all you need to do is bind that dataSource like this way this.dataSource = changes // changes gives you object which contain a previews value and current value so you need to value bind the current value it would be great if you show me the log of changes – Yash Rami Mar 29 '19 at 12:46
  • https://stackoverflow.com/questions/55417522/how-to-pass-data-to-material-table-data-source-dynamically/55417653#55417653 – user1938143 Mar 29 '19 at 12:48
  • you can see this example. https://stackoverflow.com/questions/55417522/how-to-pass-data-to-material-table-data-source-dynamically/55417653#55417653 – user1938143 Mar 29 '19 at 12:49