2

I have an items array and loop it into a component. Display items props separately:

Items Array

const items = [
    {
        'name': 'item1', 
        'prop1': 'text1', 
        'prop2': 'text2',
        'boolval': true
    },
    {
        'name': 'item2', 
        'prop1': 'text1', 
        'prop2': 'text2',
        'boolval': false
    },
    {
        'name': 'item3', 
        'prop1': 'text1', 
        'prop2': 'text2',
        'boolval': true
    }];

Component

<div class="all-items">
    <app-items [item]="items"></app-items>
</div>

<div class="specific-items">
    <app-items [item]="items"></app-items>
</div>

HTML

<div class="title">List</div>
<p>Name: {{item.name}}</p>
<p>Prop1: {{item.prop1}}</p>
<p>Prop2: {{item.prop2}}</p>

I want to display all items under the .all-items div, but display item which has boolval=true prop under the .specific-items div. Generated HTML for all-items looks like the following:

<div class="all-items">
    <app-items>
        <div class="title">List</div>
        <p>Name: item1</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
    <app-items>
        <div class="title">List</div>
        <p>Name: item2</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
    <app-items>
        <div class="title">List</div>
        <p>Name: item3</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
</div>

I want to display specific items like this;

<div class="specific-items">
    <app-items [item]="items.filter(x => x.boolval=== true)"></app-items>
</div>

<div class="specific-items">
    <app-items>
        <div class="title">List</div>
        <p>Name: item1</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>

        <p>Name: item3</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
</div>

How can I generate a specific array in template like this [item]="items.filter(x => x.boolval=== true)" and pass it to component? So I want generate a specific array in template and then send it to component

4
  • What are you expecting .map(x => x.bool === true) to do? This will return a new array of booleans You probably wanted .filter instead (you should use a Pipe for that though angular.io/guide/pipes) . That said, you should either use a component getter, either generate the array first, it's not a great practice to bind a function (or a getter) to an angular component if it performs heavy operations (like array mapping). Commented Dec 31, 2018 at 12:08
  • sorry I misspelled, I've corrected map as filter Commented Dec 31, 2018 at 12:12
  • Could you have a typo in x.bool? Your array items have a field called boolval. Commented Dec 31, 2018 at 12:13
  • you're right, I've corrected, thank you Commented Dec 31, 2018 at 12:16

4 Answers 4

2

You can create a pipe to filter the array.

Here is the final solution

app-items.pipe.ts

@Pipe({
  name: 'appItemsFilter'
})
export class AppItemsFilter implements PipeTransform {

  transform(items) {
    return items.filter(x => x.boolval);
  }
}

And you can simply use it as following

<div class="all-items">
  <app-items [items]="items"></app-items>
</div>

<div class="specific-items">
  <app-items [items]="items | appItemsFilter"></app-items>
</div>

Also, this pipe is pure which means angular will not call tranform method unless items array reference change (operations like push, pop won't trigger change detection) So, performance will be a lot better than calling methods from template.

Sign up to request clarification or add additional context in comments.

Comments

1

In angular, you can try below-

    <div class="all-items">
    <app-items *ngFor="let item of items;let i= index">
        <div class="title">List</div>
      <ng-container *ngIf="item.boolval">
        <p>Name: {{item?.name}}</p>
        <p>Prop1: {{item?.prop1}}</p>
        <p>Prop2: {{item?.prop2}}</p>
      </ng-container>
    </app-items>
  </div>

Comments

1

Added the code in stackbliz

modified the HTML structure little and added some conditions.

<div class="all-items">
    <app-items [items]="items" case="1"></app-items>
</div>

<div class="specific-items">
    <app-items [items]="items" case="2"></app-items>
</div>

<div class="title">List</div>
<div *ngFor="let item of items">
    <div *ngIf="case == 1 || (case == 2 && item.boolval == true)">
        <p>Name: {{item.name}}</p>
        <p>Prop1: {{item.prop1}}</p>
        <p>Prop2: {{item.prop2}}</p>
    </div>
</div>

Comments

1

you can pass pipe direclty to the array to *ngFor

@Pipe({
 name: 'itemsFilter'
})
export class AppItemsFilter implements PipeTransform {

  transform(items) {
   return items.filter(x => x.boolval);
  }
}

in your html

  <div class="specific-items">
  <app-items>
   <div class="title">List</div>
   <ng-container *ngFor="let item of items | itemsFilter">
      <p>Name: {{item?.name}}</p>
      <p>Prop1: {{item?.prop1}}</p>
      <p>Prop2: {{item?.prop2}}</p>
    <ng-container>
  </app-items>
</div>

Comments

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.