Home > Blockchain >  Refresh component child on other component child changes
Refresh component child on other component child changes

Time:01-12

I have two child components who are called from a parent as:

HTML

<app-profile-form [profile]="profile"></app-profile-form>
<app-profile-activity-list [profile]="profile"></app-profile-activity-list>

This is working well; now in the second component, I have an Activity log list as follows:

HTML

<app-datatable 
          [headers]="['#', 'New value','Old value','Description']" [dataLength]="datalength"
          [data]="profileActivities"
           emptyTableMessage="No logs created">

           <tr body *ngFor="let profileActivity of profileActivities; index as i">
            <td scope="row">{{ i   1 }}</td>
            <td>{{profileActivity.newValue}}</td>
            <td>{{profileActivity.oldValue}}</td>
            <td>{{profileActivity.description}}</td>
           </tr>
           </app-datatable>

TS:

export class ProfileActivityListComponent implements OnInit {
  @Input() profile: ProfileModel;
   profileActivities: ProfileActivity[];

    constructor(
        public apiService: ApiService,
      ) { }
    
      ngOnInit() {
    
        let profileActivityRequestModel = {
            profileId:  this.profile.id,
            ...this.pagination
        }
        this.profileRequest =  profileActivityRequestModel;
    
    
        this.apiService.profileActivityService.getPagedFilteredList(this.profileRequest).subscribe((result) => {
            this.profileActivities = result.resourceModel;
            this.datalength = this.profileActivities.length;
            let totalPages = result.total ? Math.ceil(result.total / result.limit) : 1;
            this.pagination = {
              ...this.pagination,
              total: result.total,
              totalPages: totalPages,
              page: result.offset   1
            }
          });
      }

And finally, in the first child model, I have a form where at the final of the day, calls the API and return a response as:

TS

 submitForm() {
     this.store.dispatch(new ProfileActions.AddProfile(newProfile));
   }

This last call to API inserts data on the database that the second child component should retrieve. But changes are not reflected until I refresh the page. Is there a way to refresh the second component table info after the first component submit?

UPDATE The this.store.dispatch(new ProfileActions.AddProfile(newProfile)); executes an Action, Effect and Reducer as:

Action

export enum ProfileActionTypes {
ADD_PROFILE = '[PROFILES] Add PROFILE'
}
    export class AddProfile implements Action {
      readonly type = ProfileActionTypes.ADD_PROFILE;
      constructor(public payload: ProfileModel) {
      }
    }

Effect:

@Effect() addNewProfile$ = this.actions$
    .pipe(ofType<AddProfile>(ProfileActionTypes.ADD_PROFILE),
      mergeMap((data) => this.profileService.addProfile(data.payload).pipe(map(result => {
        if (data.payload.status === 3) {
          this.toast.success('Profile DELETED', 'Success');
          return new DeleteProfileSuccess(result);
        }
        if (data.payload.id > 0) {
          this.toast.success(`${result.firstName} ${result.lastName} Profile UPDATED`, 'Success');
        } else {
          this.toast.success(`${result.firstName} ${result.lastName} Profile ADDED`, 'Success');
        }
        return new AddProfileSuccess(result);
      }))));

Reducer

export function profilesReducer(state = initialState, action: ProfilesActions) {

 case ProfileActionTypes.ADD_PROFILE:
      return {
        ...state
      };
}

CodePudding user response:

You can achive it by using @Output() event emitter and @Viewchild() decorator, Follow below steps

Define @Output() event emitter into your app-profile-form.component.ts file as below

@Output() public dataSaved = new EventEmitter<boolean>();

/* Emit an event when data is get saved, from your profile-form component as below */
 submitForm() {
     this.store.dispatch(new ProfileActions.AddProfile(newProfile));
     setTimeout({
         this.dataSaved.emit(true);
     }, 100);
 }

Bind event into your parent component and add reference into your profile-activity-component selector for viewchild

<app-profile-form [profile]="profile" (dataSaved)="refreshActivityList($event)"></app-profile-form>
<app-profile-activity-list [profile]="profile" #refProfileActivity></app-profile-activity-list>

Define refreshActivityList() method into your parent component and create @viewChild() for your profile-activity component

@ViewChild('refProfileActivity') refProfileActivity: ProfileActivityListComponent;

public refreshActivityList(event) {
  if (event) {
    this.refProfileActivity.getList();
  }
}

Last but not least move yout API call from ngOnInit() hook to into any specific function ProfileActivityListComponent TS file as below

export class ProfileActivityListComponent implements OnInit {
  @Input() profile: ProfileModel;
  profileActivities: ProfileActivity[];

  constructor(public apiService: ApiService) {}

  ngOnInit() {
    this.getList();
  }

  public getList() {
    let profileActivityRequestModel = {
      profileId: this.profile.id,
      ...this.pagination,
    };
    this.profileRequest = profileActivityRequestModel;

    this.apiService.profileActivityService
      .getPagedFilteredList(this.profileRequest)
      .subscribe((result) => {
        this.profileActivities = result.resourceModel;
        this.datalength = this.profileActivities.length;
        let totalPages = result.total
          ? Math.ceil(result.total / result.limit)
          : 1;
        this.pagination = {
          ...this.pagination,
          total: result.total,
          totalPages: totalPages,
          page: result.offset   1,
        };
      });
  }
}

Thanks!

  • Related