ngx-datatable
ngx-datatable copied to clipboard
ExpressionChangedAfterItHasBeenCheckedError
[x] bug report => search github for a similar issue or PR before submitting [ ] feature request [ ] support request => Please do not submit support request here, post on Stackoverflow or Gitter
Current behavior
It's looks like it relates to other library, but it's interferes with ngx-datatable
, at least I reproduced in that connection
When I show modal window from ng-bootstrap by handling (select)
output I get
ng:///NgxDatatableModule/DataTableBodyRowComponent.ngfactory.js:12 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'datatable-body-cell sort-active active'. Current value: 'datatable-body-cell sort-active'.
it works fine when I show the same modal by (click)
on some button on the page, but it raise each time I do that by (select)
, and when it happens, next modal activate
break the page
Reproducing Fully reproduced with last angular and both packages here http://plnkr.co/edit/Ru8xoU3PNOqu4S1qUfbn?p=preview
Intersting, but in case I put some button in column
<ngx-datatable-column name="Registration Date"
prop="registrationDate"
[resizeable]="false"
[flexGrow]="1">
<ng-template let-row="row" let-value="value" ngx-datatable-cell-template>
<button
class="btn-primary btn"
(click)="emptyClickHandler()">Edit</button>
</ng-template>
</ngx-datatable-column>
So I have both
(activate)="click()"
as table component input
and
(click)="emptyClickHandler()"
as button (click) input
there are no error.
Getting the same error in a similar situation: instead of bringing up the dialog when the row is selected, I have a column that shows an icon (just a span) which has a click event handler to bring up the ng-bootstrap dialog. If I put the click handler on a button instead of the icon, it works.
Hello, do we have any updates regarding this issue?
Exact same situation as @BotanMan . Trying to open BootstrapModal with dyn. component only that I'm using (active)
not (select)
to fire the modal. But exact same Error.
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'datatable-body-cell sort-active active'. Current value: 'datatable-body-cell sort-active'.
any news? @amcdnl ?
Same issue I am facing that when i click on my icon in ngx-datatable column open modal it works fine but showing same error in my console.
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'datatable-body-cell sort-active active'. Current value: 'datatable-body-cell sort-active'.
Do we have any updates regarding this issue?
Any updates to this issue i am getting the same error:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'datatable-body-cell sort-active active'. Current value: 'datatable-body-cell sort-active'.
Is it related to https://github.com/angular/angular/issues/17572 by any chance?
I am still facing the issue. If i got a solution i comment on git hub in this topic
On Wed, Aug 2, 2017 at 3:47 PM, Max [email protected] wrote:
Is it related to angular/angular#17572 https://github.com/angular/angular/issues/17572 by any chance?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/swimlane/ngx-datatable/issues/721#issuecomment-319631345, or mute the thread https://github.com/notifications/unsubscribe-auth/AO5u-SfZkasULbqWGBE_N8mGFySLstN2ks5sUEyygaJpZM4NLbKd .
-- Thanks & Regards
[image: Oodles Technologies Pvt Ltd] http://www.oodlestechnologies.com/
Himanshu Khurana Assistant Consultant-UI, Oodles Technologies Pvt Ltd Phone: +91 124 4368 395 Mobile: +91 9899442240 Email: [email protected] [email protected] Website: http://www.oodlestechnologies.com/ Skype: himanshukhurana.oodles
[image: Twitter] https://twitter.com/oodlestech [image: Facebook] https://www.facebook.com/OodlesTech [image: Google +] https://plus.google.com/+Oodlestechnologies/posts [image: LinkedIn] https://www.linkedin.com/company/oodles-technologies-pvt-ltd
I'm not very proud of this solution, but the only way I got it to work is by blurring the datatable-body-cell
right before emptyClickHandler
main logic. We can target it by passing a reference to the template element and then looking up the parent of the parent (btnElement.parentElement.parentElement
)
Something like this:
HTML:
<ngx-datatable-column name="Registration Date"
prop="registrationDate"
[resizeable]="false"
[flexGrow]="1">
<ng-template let-row="row" let-value="value" ngx-datatable-cell-template>
<button #btnElement
class="btn-primary btn"
(click)="emptyClickHandler(btnElement)">Edit</button>
</ng-template>
</ngx-datatable-column>
JS:
emptyClickHandler(btnElement) {
btnElement && btnElement.parentElement && btnElement.parentElement.parentElement &&
btnElement.parentElement.parentElement.blur();
// ... Other logic here .. say to open a modal window
}
I think this error is causing by the cell is deactive by popping up a modal, since it loses focus. The problem is the table component has been checked by angular and now it is changed by the modal. Therefore, it throws an error like ExpressionChangedAfterItHasBeenCheckedError
.
To prevent this error, I think the best way is preventing the cell become active or as soon as it becomes active, deactivate it.
onActive(event) {
(event.type === 'click') && event.cellElement.blur();
}
I couldn't get this to work @maxisam. Your solution relies on event bubbling which makes its reponse too late - the error has already happened. Shame because I thought it looked like a more elegant solution.
@torontocode http://plnkr.co/edit/y2rPVs32V09nSEuffD3W?p=preview
For the timebeing I wrapped the code at which this occurs in a setTimeout.
setTimeout(() => {
//Code that triggers the error
})
Our case called for something a little different (because we needed to call event.stopPropagation()
to prevent selection (onSelect
) of the row (so @torontocode 's solution worked).
component.ts
...
public deleteField(event: any, row: any, firstChild: any): void {
event.stopPropagation();
firstChild && firstChild.parentElement && firstChild.parentElement.parentElement &&
firstChild.parentElement.parentElement.blur();
// open delete modal
this.modalService.open(DeleteComponent);
...
}
public onSelect($event): void {
// navigate to details page
}
...
component.html
<ngx-datatable-column>
<ng-template ngx-datatable-cell-template let-row="row">
<div #firstChild>
<div (click)="deleteField($event, row, firstChild)" class="field-delete text-center">
<i class="fa fa-trash"></i>
</div>
</div>
</ng-template>
</ngx-datatable-column>
Does anyone know if there's a better way to do this so that we could use the onActive method (bypassing the onSelect
) ?
As @maxisam noted, calling event.cellElement.blur() from (activate) works for me.
component.html
<ngx-datatable
#datatable
class="custom"
[columns]="columns"
[rows]="rows"
[selected]="selected"
[loadingIndicator]="loadingIndicator"
[columnMode]="'force'"
[headerHeight]="40"
[footerHeight]="0"
[rowHeight]="'auto'"
[reorderable]="false"
[sortType]="'single'"
[selectionType]="'single'"
[selectCheck]="singleSelectCheck"
(activate)="onActivate($event)">
</ngx-datatable>
component.ts
onActivate(event: any) {
if (event.type === 'dblclick') {
event.cellElement.blur();
this.edit(event);
}
}
Same issue. I had to use both the onActivate from @maxtacco and @maxisam and the setTimeout from @ScottSpittle to get rid of the error. Neither worked for me by themselves.
Call event.cellElement.blur(); when click worked for me 👍
I am reporting that I am also experiencing this issue.
using
@maxisam - I was able to clear the error with your suggestion, thank you! Hopefully there will be some fix for this in the core library and I can remove this hack or find a better way around this without having to subscribe to activate()
, as I do not need it for any other prupose
Error happens for us, it indicates that ngx-datatable is violating Angular's one way data flow. In development mode and non-AOT production builds luckily the only bad effect is the warning. With an AOT compiled build you get data synchronocity issues 😒
@maxtacco is this event only work for active? why the click event doesn't have the cellElement property?
@needforspeed I needed that for double click, but as @maxisam showed it should work for single click as well.
Anyone managed to fix this?
No solution seems to be working.
@xyrintech you could wrap ngx-datatables in an ng-container and use an *ngIf="...; let ..."
over your stream. That's what I did anyway. Works around the bug.
I understand, may I have the sample code for this?
<ng-container *ngIf="stream$ | async; let value">
then use the resolved value
instead of stream$
. No empty stream no troubles.
Any updates on this? We are running into the same issue...
I encountered this same issue today
I also encounter this problem today. I had to implement the workaround as others have mentioned above. My template:
prop="job_id"
[width]="80"
[sortable]="false">
<ng-template let-row="row" ngx-datatable-cell-template>
<span class="btn-link fake-link" (click)="getTranLog(row.job_id, $event)">{{row.job_id}}</span>
</ng-template>
</ngx-datatable-column>
And in my component:
event.target.parentElement.parentElement.blur();
this.modalRef = this._modalSvc.open(TranLogModalComponent);
this.modalRef.componentInstance.jobID = jobID;
}```
Same problem, resolved with blur...
event.target.closest('datatable-body-cell').blur();