0

I have a situation in my Angular 2 app where I am iterating over an array of objects, and if the "completed" property is set to false for any of those objects, I want to print to the view 'Yes', because there is (at least) one object with "completed" equal to false -- meaning it's still an active flag.

However, right now, the template code I have is printing 'Yes' to the view for EACH time one of these objects with the "completed" property set to false returns true. How can I adjust this code so that I'm only getting "Yes" printed once if ANY ONE (or more) of the objects in the array being iterated over has that "completed" property set to true?

Here's my code:

<td *ngFor="let flag of service.flags">
     <ng-template *ngIf="flag?.completed === false"> 
        <span class="standard-flag">Yes</span>
     </ng-template> 
</td> 

I also tried using the ternary operator, but it gives me the same result:

<td *ngFor="let flag of service.flags">
     <ng-template *ngIf="flag?.completed === false ? true : false""> 
        <span class="standard-flag">Yes</span>
     </ng-template> 
</td> 

While I would normally handle the logic in the component, I'm thinking there must be a way, perhaps with indexing, that I could this in the view on this occasion.

2
  • I would do the iteration within the component.ts file and then set a variable (this.completed) to true when any of them returns true. Then, within the template, you can assign an attribute to show "yes": [hidden] = "completed" on a DOM element: <h1 [hidden] = "completed">Yes</h1>. Commented Jul 27, 2017 at 22:14
  • I agree, and normally I would do this in the component and print to the view the result. However in this particular case (for reasons I don't want to go into) I'd rather handle it in the view directly. I'm thinking there must be a way to do this with indexing of some sort. Commented Jul 27, 2017 at 22:15

1 Answer 1

0

You don't need an ngFor to make this work. ngFor repeats for every element in your array, that's why you see a bunch Yes's

Use Array.some() which returns true immediately if at least one of the elements in the array returns true, so it is the right tool for the job here

<td>
    <span *ngIf="service.flags.some(flag => flag.completed === false) === true">
        Yes
    </span>
</td> 
Sign up to request clarification or add additional context in comments.

12 Comments

Sounds promising. Will give it a try. I didn't realize I could essentially iterate over all of the objects in the array without using *ngFor.
Getting an error: zone.js:522 Unhandled Promise rejection: Template parse errors: Parser Error: Bindings cannot contain assignments at column 42 in [service.flags.some(flag => flag.completed === false) === true]
Sounds strange, try refactoring this service.flags.some(flag => flag.completed === false) === true into a function and call the function inside ngIf instead
Yup, that would probably work. But in this case I'm trying to handle this logic in the view specifically.
Yeah, just do as you please, it is your code, but I think adding a function to your component class is much easier and less an overkill for what you are trying to achieve. Just an opinion
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.