user2280016
user2280016

Reputation: 1850

Is there a unique filter in angular 2?

I have a json as follows:

[{
  "_id": "58a58ea23744cd46918914ef",
  "entityId": "ce7200c1-3430-47ce-ab81-7d0622cb8cae",
  "name": "Portugal",
  "description": "Portugal",
  "type": "country",
  "category": "common",
  "subcategory": "common",
  "parent": {
    "_id": "58a8486ca4890027348a8966"
  },
  "image": {
    "_id": "58a8486ca4890027348a8965"
  },
  "metadata": {
    "primary": "pt",
    "taxRate": 20,
    "exchangeRate": 0.7,
    "language": "PT",
    "currency": "EUR",
    "_id": "58a8486ca4890027348a8964"
  }
}, {
  "_id": "58a58ea23744cd46918914f1",
  "entityId": "815b9e90-e36f-4488-ad50-6a259b6d034d",
  "name": "Qatar",
  "description": "Qatar",
  "type": "country",
  "category": "common",
  "subcategory": "common",
  "parent": {
    "_id": "58a8486ca4890027348a8969"
  },
  "image": {
    "_id": "58a8486ca4890027348a8968"
  },
  "metadata": {
    "primary": "qa",
    "taxRate": 20,
    "exchangeRate": 0.7,
    "language": "RO",
    "currency": "RO",
    "_id": "58a8486ca4890027348a8967"
  }
}, {
  "_id": "58a58ea23744cd46918914f2",
  "entityId": "e12ea227-c05c-42cf-b746-6bc537812a02",
  "name": "Romania",
  "description": "Romania",
  "type": "country",
  "category": "common",
  "subcategory": "common",
  "parent": {
    "_id": "58a8486ca4890027348a896c"
  },
  "image": {
    "_id": "58a8486ca4890027348a896b"
  },
  "metadata": {
    "primary": "ro",
    "taxRate": 20,
    "exchangeRate": 0.7,
    "language": "RO",
    "currency": "RON",
    "_id": "58a8486ca4890027348a896a"
  }
}, {
  "_id": "58a58ea23744cd46918914f4",
  "entityId": "8c22ccaf-f7b7-4009-9642-54580ad5ad4e",
  "name": "Russia",
  "description": "Russia",
  "type": "country",
  "category": "common",
  "subcategory": "common",
  "parent": {
    "_id": "58a8486ca4890027348a8972"
  },
  "image": {
    "_id": "58a8486ca4890027348a8971"
  },
  "metadata": {
    "primary": "ru",
    "taxRate": 20,
    "exchangeRate": 0.7,
    "language": "RU",
    "currency": "RUB",
    "_id": "58a8486ca4890027348a8970"
  }
}, {
  "_id": "58a58ea23744cd46918914fa",
  "entityId": "725b2011-177b-4fc5-8e1f-559b3e4e8958",
  "name": "United States",
  "description": "United States",
  "type": "country",
  "category": "common",
  "subcategory": "common",
  "parent": {
    "_id": "58a8486ca4890027348a8984"
  },
  "image": {
    "_id": "58a8486ca4890027348a8983"
  },
  "metadata": {
    "primary": "us",
    "taxRate": 20,
    "exchangeRate": 0.7,
    "language": "EN",
    "currency": "USD",
    "_id": "58 a8486ca4890027348a8982"
  }
}, {
  "_id": " 58 a58ea23744cd46918914d8",
  "entityId": "af884be9 - 067 d - 4 dd2 - 8646 - 5738 f5bb0efb",
  "name": "Germany",
  "description": "Germany",
  "type": "country",
  "category": "common",
  "subcategory": "common",
  "parent": {
    "_id": "58 a8486ca4890027348a89b7 "
  },
  "image": {
    "_id": "58 a8486ca4890027348a89b6 "
  },
  "metadata": {
    "primary": "de",
    "taxRate": 20,
    "exchangeRate": 0.7,
    "language": "DE",
    "currency": "EUR",
    "_id": "58 a8486ca4890027348a89b5 "
  }
}]

And I'm displaying these values in dropdown with the following code:

Template:

<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true">
    {{selectedCurrency}}
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <li *ngFor="let currency of currencies">
      <a>{{currency.metadata.currency }}</a>
    </li>
  </ul>
</div>

Right now if you see, metadata has duplicate currency "EUR" . Is there a pipe with angular2 so that I can display only the unique values of metadata.currency

Upvotes: 4

Views: 25042

Answers (2)

developer033
developer033

Reputation: 24894

Is there a unique filter in angular 2?

No, you would have to create your custom pipe to do this.

However, I don't think create a pipe is really necessary, you can do it in your component.

You can get all the unique currencies of those items doing the following:

export class AnyComponent {

  items: any[];
  currencies: string[];

  constructor() {
    // Populate your items... "items = blabla"

    // Get all currencies
    const curr = items.map(data => data.metadata.currency);

    // Unique currencies
    this.currencies = curr.filter((x, i, a) => x && a.indexOf(x) === i);
  }
}

Then, in your template:

...
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
  <li *ngFor="let currency of currencies">
    <a>{{currency}}</a>
  </li>
</ul>

Upvotes: 14

user663031
user663031

Reputation:

Is there a unique filter in angular 2?

No, there is not.

You should create the unique list in your component JS logic, for the same reason that it is recommended not to use pipes for filtering and sorting.

From https://angular.io/docs/ts/latest/guide/pipes.html#!#no-filterpipe-or-orderbypipe-:

Filtering and especially sorting are expensive operations. The user experience can degrade severely for even moderate sized lists when Angular calls these pipe methods many times per second.

You can create the unique list of currencies, omitting missing ones, with something like:

this.uniqueCurrencies = uniq(data.map(elt => elt.metadata.currency).filter(Boolean));

where uniq is any one of many versions available from libraries, or roll your own, or use Set as proposed in another answer.

Upvotes: 4

Related Questions