Indeed, each time change detection is triggered, the function is executed and its result is assigned to the input property.
If two consecutive calls to the function return different values, an exception occurs in devMode, such as:
hasNextValue() {
return {};
}
Exception: Expression has changed ...
It is not recommended to bind directly to functions. Instead, assign the result to a property and then bind to that property. Although it can work if you're aware of what you're doing.
update
So, returning true or false based on internal state is not allowed? It's strange because my navigation still functions.
In fact, this practice is permissible. If the state changes due to an event (like a click or timeout), Angular expects those changes during change detection. However, if Angular triggers change detection twice without any relevant event occurring between, it throws the aforementioned exception. The issue arises when change detection itself causes modifications.
The following example would also trigger an exception because change detection modifies the component's state directly (
this.someState = !this.someState;
):
someState:boolean = false;
hasNextValue() {
this.someState = !this.someState;
return this.someState;
}
Consequently, two successive calls would produce false
and then true
, despite no external events.
However, the next example works well:
someState:boolean = false;
@HostListener('click') {
this.someState = !this.someState;
}
hasNextValue() {
return this.someState;
}
Here, two subsequent calls will yield consistent results even without any intermediate events.