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!