Evaluating *ngIf inside every *nFor loop in Angular 7












2














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.










share|improve this question
























  • 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


















2














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.










share|improve this question
























  • 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
















2












2








2







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.










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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




















  • 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



















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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python