Angular JS

Angular KeyValue Pipe

황기하 2022. 1. 15.

https://www.tektutorialshub.com/angular/angular-keyvalue-pipe/

 

Angular KeyValue Pipe - TekTutorialsHub

The KeyValue Pipe converts given Object or Map into an array of key-value pairs. We can use this with the ngFor to loop through the object keys.

www.tektutorialshub.com

The KeyValue Pipe converts given Object or Map into an array of key-value pairs. We can use this with the ngFor to loop through the object keys. The keyValue accepts the one argument compareFn, which we can use to set the custom sort to the pipe. In this tutorial, let us learn how to make use of KeyValue pipe with example.

How it works

Consider, that you have the following object and a map object. It has property a,b & c. We cannot use ngFor to iterate over it as it requires an array. This is where the KeyValue pipe comes into play. It will convert them to an array of key-value pair

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
obj = {
  c: 123,
  b: 456,
  a: 789,
};
 
 
mapObj = new Map([
   ['c', 123],
   ['b', 446],
   ['a', 789],
]);
 

We use keyvalue just like any other pipes in Angular and as shown below

1
2
3
4
5
 
obj | keyvalue
 
mapObj | keyvalue
 

The keyValue converts them and returns in the following format. each property of the object a: 789 is converted to an object with name as key and value as value { key:a, value:789 }. It creates array of such objects and returns it.

1
2
3
4
5
6
7
 
obj = [
    { key:a, value:789 },
    { key:b, value:446 },
    { key:c, value:123 },
  ];
 

Now we can use the ngFor to loop through it and display the content.

1
2
3
4
5
6
7
8
9
10
11
12
 
<ul>
  <li *ngFor="let item of obj | keyvalue">
    {{item.key}} ---> {{item.value}}</li>
</ul>
 
//output
 
a ---> 789
b ---> 456
c ---> 123
 

Default Sorting

KeyValue pipe uses the key to sort the results array. You can see it from the above example. Even though our object was c,b & a it was sorts it as a,b,c. The keyValue pipe uses the defaultComparator to sort the result. It uses

  1. Ascending Order if the keys are number
  2. Alphabetical Order if keys are strings
  3. if keys are are of different types. then covert them to to their string values and use Alphabetical Order
  4. If key is a either Null or undefined, put then at the end of the sort.


BEST ANGULAR BOOKS
The Top 8 Best Angular Books, which helps you to get started with Angular  

Custom Sorting

You can customize it by providing a custom sort function (compareFn) as the first argument to the keyValue pipe

The syntax for the compareFn as shown below. It accepts first & second keyValue and must return a number. The number must be a zero if values are equivalent else either a negative number or positive number

1
2
3
 
compareFn (a: KeyValue, b: KeyValue) => number
 

The following are three compareFn

1
2
3
4
5
6
7
8
9
10
11
12
13
 
orderOriginal = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
  return 0
}
  
orderbyValueAsc = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
   return a.value > b.value ? -1 : (a.value > b.value) ? 0 : 1  
}
 
orderbyValueDsc = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
  return a.value > b.value ? 1 : (a.value > b.value) ? 0 : -1  
}
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
<ul>
  <li *ngFor="let item of obj | keyvalue">
    {{item.key}} ---> {{item.value}}</li>
</ul>
 
//Output
a ---> 789
b ---> 456
c ---> 123
 
 
<ul>
  <li *ngFor="let item of obj | keyvalue : orderOriginal">
    {{item.key}} ---> {{item.value}}</li>
</ul>
 
//Output
b ---> 456
c ---> 123
a ---> 78
 
 
<ul>
  <li *ngFor="let item of obj | keyvalue : orderbyValueAsc ">
    {{item.key}} ---> {{item.value}}</li>
</ul>
 
//Output
a ---> 789
b ---> 456
c ---> 123
 
 
<ul>
  <li *ngFor="let item of obj | keyvalue : orderbyValueDsc ">
    {{item.key}} ---> {{item.value}}</li>
</ul>
 
//Output
c ---> 123
b ---> 456
a ---> 789
 

KeyValue Pipe Example

Consider the following breeds of dogs. The example sorts the list based on the number of sub breeds. The final code is as shown below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
breeds=
    {
      "corgi": ["cardigan"],
      "deerhound": ["scottish"],
      "bulldog": ["boston", "english", "french"],
      "mastiff": ["bull", "english", "tibetan"],
      "australian": ["shepherd"],
      "greyhound": ["italian"],
      "buhund": ["norwegian"],
      "hound": ["afghan", "basset", "blood", "english", "ibizan", "plott", "walker"],
      "bullterrier": ["staffordshire"],
    }
 

CompareFn

1
2
3
4
5
 
  orderClause = (a: KeyValue<number,[string]>, b: KeyValue<number,[string]>): number => {
    return a.value.length > b.value.length ? -1 : (a.value.length > b.value.length) ? 0 : 1  
  }
 

Template

1
2
3
4
5
6
 
<ul>
  <li *ngFor="let item of breeds | keyvalue : orderClause ">
    {{item.key}} ---> {{item.value}}</li>
</ul>
 

The output

1
2
3
4
5
6
7
8
9
10
11
 
hound ---> afghan,basset,blood,english,ibizan,plott,walker
bulldog ---> boston,english,french
mastiff ---> bull,english,tibetan
corgi ---> cardigan
deerhound ---> scottish
australian ---> shepherd
greyhound ---> italian
buhund ---> norwegian
bullterrier ---> staffordshire
 

Reference

  1. KeyValue Pipe API
  2. Async Pipe API
  3. KeyValue Pipe Source Code

댓글