Evaluating *ngIf inside every *nFor loop in Angular 7
I'm trying to use the following statement in my Angular template
<ng-container *ngFor="let sequence of sequences; let i = index">
<div *ngIf="displayNewDate(sequence.start)">
<p>{{ sequence.start | date:'shortDate' }}</p>
</div>
{{ sequence.content }}
</ng-container>
Where as the method displayNewDate(sequence.start)
checks if the current date has been displayed, and displays it if not. Therefor I want the *ngIf to vary between true and false.
public displayNewDate(current) {
const currentDate: Date = new Date(current);
if (!this.previousDate) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() < currentDate.getFullYear()) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() == currentDate.getFullYear() && this.previousDate.getMonth() < currentDate.getMonth()) {
this.previousDate = currentDate;
return true;
} else {
return false;
}
}
However I get the following in the console:
ERROR Error: "ExpressionChangedAfterItHasBeenCheckedError: Expression
has changed after it was checked. Previous value: 'ngIf: true'.
Current value: 'ngIf: false'."
Is this a limitation to the *ngIf directive? If so, is there an alternative way to get a list of sequences, and everytime a sequence beginning at a date different from the previous sequence, display the new date above the given sequence.
angular ngfor angular-ng-if angular7
|
show 1 more comment
I'm trying to use the following statement in my Angular template
<ng-container *ngFor="let sequence of sequences; let i = index">
<div *ngIf="displayNewDate(sequence.start)">
<p>{{ sequence.start | date:'shortDate' }}</p>
</div>
{{ sequence.content }}
</ng-container>
Where as the method displayNewDate(sequence.start)
checks if the current date has been displayed, and displays it if not. Therefor I want the *ngIf to vary between true and false.
public displayNewDate(current) {
const currentDate: Date = new Date(current);
if (!this.previousDate) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() < currentDate.getFullYear()) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() == currentDate.getFullYear() && this.previousDate.getMonth() < currentDate.getMonth()) {
this.previousDate = currentDate;
return true;
} else {
return false;
}
}
However I get the following in the console:
ERROR Error: "ExpressionChangedAfterItHasBeenCheckedError: Expression
has changed after it was checked. Previous value: 'ngIf: true'.
Current value: 'ngIf: false'."
Is this a limitation to the *ngIf directive? If so, is there an alternative way to get a list of sequences, and everytime a sequence beginning at a date different from the previous sequence, display the new date above the given sequence.
angular ngfor angular-ng-if angular7
That is not related to for-if combination. Even more - it is not related to ngIf perse but the way angular binds values to UI (and checks for modifications afterwards)
– Antoniossss
Nov 12 '18 at 21:26
1
Your method is supposed to be idempotent: if nothing else changes in the state of your app, two subsequent calls to the method with the same argument are supposed to return the same value. That's not the case. Don't change the state of your component when evaluating an expression, i.e. calling a getXxx method.
– JB Nizet
Nov 12 '18 at 21:27
@JBNizet What are the alternatives?
– Gjert G
Nov 12 '18 at 21:31
No, you can't do that.
– JB Nizet
Nov 12 '18 at 21:31
1
Use the actual state to return the correct value. Get the actual previous date from the array, and check if it's different from the current one. Or precompute that once, storing in each sequence if it should display the start or not. This method is called at each change detection, for each sequence. Not just once for each sequence.
– JB Nizet
Nov 12 '18 at 21:33
|
show 1 more comment
I'm trying to use the following statement in my Angular template
<ng-container *ngFor="let sequence of sequences; let i = index">
<div *ngIf="displayNewDate(sequence.start)">
<p>{{ sequence.start | date:'shortDate' }}</p>
</div>
{{ sequence.content }}
</ng-container>
Where as the method displayNewDate(sequence.start)
checks if the current date has been displayed, and displays it if not. Therefor I want the *ngIf to vary between true and false.
public displayNewDate(current) {
const currentDate: Date = new Date(current);
if (!this.previousDate) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() < currentDate.getFullYear()) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() == currentDate.getFullYear() && this.previousDate.getMonth() < currentDate.getMonth()) {
this.previousDate = currentDate;
return true;
} else {
return false;
}
}
However I get the following in the console:
ERROR Error: "ExpressionChangedAfterItHasBeenCheckedError: Expression
has changed after it was checked. Previous value: 'ngIf: true'.
Current value: 'ngIf: false'."
Is this a limitation to the *ngIf directive? If so, is there an alternative way to get a list of sequences, and everytime a sequence beginning at a date different from the previous sequence, display the new date above the given sequence.
angular ngfor angular-ng-if angular7
I'm trying to use the following statement in my Angular template
<ng-container *ngFor="let sequence of sequences; let i = index">
<div *ngIf="displayNewDate(sequence.start)">
<p>{{ sequence.start | date:'shortDate' }}</p>
</div>
{{ sequence.content }}
</ng-container>
Where as the method displayNewDate(sequence.start)
checks if the current date has been displayed, and displays it if not. Therefor I want the *ngIf to vary between true and false.
public displayNewDate(current) {
const currentDate: Date = new Date(current);
if (!this.previousDate) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() < currentDate.getFullYear()) {
this.previousDate = currentDate;
return true;
} else if (this.previousDate.getFullYear() == currentDate.getFullYear() && this.previousDate.getMonth() < currentDate.getMonth()) {
this.previousDate = currentDate;
return true;
} else {
return false;
}
}
However I get the following in the console:
ERROR Error: "ExpressionChangedAfterItHasBeenCheckedError: Expression
has changed after it was checked. Previous value: 'ngIf: true'.
Current value: 'ngIf: false'."
Is this a limitation to the *ngIf directive? If so, is there an alternative way to get a list of sequences, and everytime a sequence beginning at a date different from the previous sequence, display the new date above the given sequence.
angular ngfor angular-ng-if angular7
angular ngfor angular-ng-if angular7
edited Nov 15 '18 at 13:48
Goncalo Peres
1,3261318
1,3261318
asked Nov 12 '18 at 21:22
Gjert G
2331827
2331827
That is not related to for-if combination. Even more - it is not related to ngIf perse but the way angular binds values to UI (and checks for modifications afterwards)
– Antoniossss
Nov 12 '18 at 21:26
1
Your method is supposed to be idempotent: if nothing else changes in the state of your app, two subsequent calls to the method with the same argument are supposed to return the same value. That's not the case. Don't change the state of your component when evaluating an expression, i.e. calling a getXxx method.
– JB Nizet
Nov 12 '18 at 21:27
@JBNizet What are the alternatives?
– Gjert G
Nov 12 '18 at 21:31
No, you can't do that.
– JB Nizet
Nov 12 '18 at 21:31
1
Use the actual state to return the correct value. Get the actual previous date from the array, and check if it's different from the current one. Or precompute that once, storing in each sequence if it should display the start or not. This method is called at each change detection, for each sequence. Not just once for each sequence.
– JB Nizet
Nov 12 '18 at 21:33
|
show 1 more comment
That is not related to for-if combination. Even more - it is not related to ngIf perse but the way angular binds values to UI (and checks for modifications afterwards)
– Antoniossss
Nov 12 '18 at 21:26
1
Your method is supposed to be idempotent: if nothing else changes in the state of your app, two subsequent calls to the method with the same argument are supposed to return the same value. That's not the case. Don't change the state of your component when evaluating an expression, i.e. calling a getXxx method.
– JB Nizet
Nov 12 '18 at 21:27
@JBNizet What are the alternatives?
– Gjert G
Nov 12 '18 at 21:31
No, you can't do that.
– JB Nizet
Nov 12 '18 at 21:31
1
Use the actual state to return the correct value. Get the actual previous date from the array, and check if it's different from the current one. Or precompute that once, storing in each sequence if it should display the start or not. This method is called at each change detection, for each sequence. Not just once for each sequence.
– JB Nizet
Nov 12 '18 at 21:33
That is not related to for-if combination. Even more - it is not related to ngIf perse but the way angular binds values to UI (and checks for modifications afterwards)
– Antoniossss
Nov 12 '18 at 21:26
That is not related to for-if combination. Even more - it is not related to ngIf perse but the way angular binds values to UI (and checks for modifications afterwards)
– Antoniossss
Nov 12 '18 at 21:26
1
1
Your method is supposed to be idempotent: if nothing else changes in the state of your app, two subsequent calls to the method with the same argument are supposed to return the same value. That's not the case. Don't change the state of your component when evaluating an expression, i.e. calling a getXxx method.
– JB Nizet
Nov 12 '18 at 21:27
Your method is supposed to be idempotent: if nothing else changes in the state of your app, two subsequent calls to the method with the same argument are supposed to return the same value. That's not the case. Don't change the state of your component when evaluating an expression, i.e. calling a getXxx method.
– JB Nizet
Nov 12 '18 at 21:27
@JBNizet What are the alternatives?
– Gjert G
Nov 12 '18 at 21:31
@JBNizet What are the alternatives?
– Gjert G
Nov 12 '18 at 21:31
No, you can't do that.
– JB Nizet
Nov 12 '18 at 21:31
No, you can't do that.
– JB Nizet
Nov 12 '18 at 21:31
1
1
Use the actual state to return the correct value. Get the actual previous date from the array, and check if it's different from the current one. Or precompute that once, storing in each sequence if it should display the start or not. This method is called at each change detection, for each sequence. Not just once for each sequence.
– JB Nizet
Nov 12 '18 at 21:33
Use the actual state to return the correct value. Get the actual previous date from the array, and check if it's different from the current one. Or precompute that once, storing in each sequence if it should display the start or not. This method is called at each change detection, for each sequence. Not just once for each sequence.
– JB Nizet
Nov 12 '18 at 21:33
|
show 1 more comment
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53270307%2fevaluating-ngif-inside-every-nfor-loop-in-angular-7%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53270307%2fevaluating-ngif-inside-every-nfor-loop-in-angular-7%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
That is not related to for-if combination. Even more - it is not related to ngIf perse but the way angular binds values to UI (and checks for modifications afterwards)
– Antoniossss
Nov 12 '18 at 21:26
1
Your method is supposed to be idempotent: if nothing else changes in the state of your app, two subsequent calls to the method with the same argument are supposed to return the same value. That's not the case. Don't change the state of your component when evaluating an expression, i.e. calling a getXxx method.
– JB Nizet
Nov 12 '18 at 21:27
@JBNizet What are the alternatives?
– Gjert G
Nov 12 '18 at 21:31
No, you can't do that.
– JB Nizet
Nov 12 '18 at 21:31
1
Use the actual state to return the correct value. Get the actual previous date from the array, and check if it's different from the current one. Or precompute that once, storing in each sequence if it should display the start or not. This method is called at each change detection, for each sequence. Not just once for each sequence.
– JB Nizet
Nov 12 '18 at 21:33