Primeng: TabView/TabPanel ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ui-helper-hidden: true'. Current value: 'ui-helper-hidden: false'

Created on 31 May 2018  路  15Comments  路  Source: primefaces/primeng

I'm submitting a ... (check one with "x")

[ x ] bug report => Search github for a similar issue or PR before submitting
[ ] feature request => Please check if request is not on the roadmap already https://github.com/primefaces/primeng/wiki/Roadmap
[ ] support request => Please do not submit support request here, instead see http://forum.primefaces.org/viewforum.php?f=35

Stackblitz Example:

https://primeng-tabview-ngif.stackblitz.io/
https://stackblitz.com/edit/primeng-tabview-ngif

Current behavior
Expression changed error when using *ngIf on a TabPanel

Expected behavior
No Expression changed error or a mechanism to set "visible" tabs programatically

Minimal reproduction of the problem with instructions
Import TabViewModule
Place p-tabView component in an Angular template
Use *ngIf on a p-tabPanel
Use browser debugger tools to see the error in the Console log

What is the motivation / use case for changing the behavior?
We require the need to hide tabs based on settings from an API

Please tell us about your environment:
Windows 8
VSCode
NPM
IIS

  • Angular version: 5.X
    Using Angular 6, issue persists

  • PrimeNG version: 5.X
    Using latest Angular and PrimeNG, issue persists

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
    Chrome 64

  • Language: [all | TypeScript X.X | ES6/7 | ES5]
    TypeScript

  • Node (for AoT issues): node --version =
    C:WINDOWSsystem32>node --version
    v8.11.1

LTS-FIXED-8.1.6 defect

Most helpful comment

Am also faced this issue.
Finally I set [selected]="true" in my first p-tabPanel. Now it works fine.

All 15 comments

Am also faced this issue.
Finally I set [selected]="true" in my first p-tabPanel. Now it works fine.

@priya-angularjs That's an interesting workaround you have found. What do you do if the first tab is the one you want to make invisible?

@KamelJabber

@priya-angularjs @mmlitvin

Interesting using the your "workaround" code is fine when setting [selected] to true or a hard coded comparison, "i == 0"

However, using a method or a Map does not work.

For example, it will not work with either of the below two techniques:

[selected]="isTabSelected('Communications')"
[selected]="activeTabIndex == iTabsMap.get('Communications')"

seems like it can't perform the eval...humph, I don't want to hard code anything since the tabs are so dynamic.
sorry, the below actually did NOT work either, it only works if I use literal "true/false" or a literal number in the equality check.

_!! Interesting, doing it with an object worked just fine:
const iTabsObject = {'Communications': 0};

[selected]="activeTabIndex === iTabsObject['Communications']"_

Please note that using this [selected] hack results in lazy tabs no longer working.

calling changeDetectorRef in ngAfterViewInit will not through that error.

import { Component, ChangeDetectorRef, AfterViewInit } from '@angular/core';
// more imports
export class TabViewComponent implements AfterViewInit {

 constructor(private cd: ChangeDetectorRef) {}

 ngAfterViewInit() {
     this.cd.detectChanges();
 }
}

@Janatbek I tried adding your code to my compoenent (i.e. the component that uses TabView/Panels) and the error is still thrown.

Tried a couple of workaround, none of them worked, providing a selected tab on your side works.

Designating a selected tab does not work if the parent p-tabView [activeIndex] is set dynamically from a component binding and the value assigned from that binding updates immediately after the component loads. We are setting the activeIndex off of a subscription to ActivatedRoute.queryParamMap, so that the selected tab is preserved across navigation. However, if the browser loads/refreshes with the an activeIndex other than the default/selected tab, the same ExpressionChangedAfterItHasBeenCheckedError appears in the browser console.

Designating a selected tab does not work if the parent p-tabView [activeIndex] is set dynamically from a component binding and the value assigned from that binding updates immediately after the component loads. We are setting the activeIndex off of a subscription to ActivatedRoute.queryParamMap, so that the selected tab is preserved across navigation. However, if the browser loads/refreshes with the an activeIndex other than the default/selected tab, the same ExpressionChangedAfterItHasBeenCheckedError appears in the browser console.

Workaround: set property for active index in timeout:
setTimeout(() => this.index = params.tab);

Thanks, @isevcik. The work-around we're going with is to place the subscription to update the activeIndex bound property manually in ngAfterViewInit instead of using an async pipe in the template. That way, the code does not get called until after Angular has first initialized the child p-tabView, so ExpressionChangedAfterItHasBeenCheckedError does not appear to reoccur.

one hacky solution to overcome the problem is to decorate panels with [selected] attribute like mentioned before.
another solution would be to attach a directive that lifts some of the burden of active index handling (for example by reading and writing the active tab to the query string)
_code_
https://stackblitz.com/edit/primeng-issues-tabview-ngif
_sample_
https://primeng-issues-tabview-ngif.stackblitz.io/?tab=three
either way, it would be great if the issue would be addressed from the inside out :)

I'm also running into this issue. The "selected" workaround, worked for me.
[selected]="index == 0"

Also same issues today, but found workaround with __changeDetectorRef__ (by Janatbek on Nov 12, 2018). Still complaining changeDetectorRef definitions in __app.module__ (providers) but works well anyway. Trying to solve app.module/provider issue next ...

Am also faced this issue.
Finally I set [selected]="true" in my first p-tabPanel. Now it works fine.

It worked for me. Thanks:)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lilling picture lilling  路  3Comments

SchneMa picture SchneMa  路  3Comments

miresk picture miresk  路  3Comments

mitosandov picture mitosandov  路  3Comments

papiroca-tm picture papiroca-tm  路  3Comments