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
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 theactiveIndex
off of a subscription toActivatedRoute.queryParamMap
, so that the selected tab is preserved across navigation. However, if the browser loads/refreshes with the anactiveIndex
other than the default/selected tab, the sameExpressionChangedAfterItHasBeenCheckedError
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:)
Most helpful comment
Am also faced this issue.
Finally I set [selected]="true" in my first p-tabPanel. Now it works fine.