【Angular】カスタムパイプの導入


Angularのカスタムパイプの導入方法について記事にしたいと思います。

Angularのパイプとは?

Angularでは、テンプレート上のフォーマットを簡単に変換できるPipeが標準装備されています。
適用方法は簡単で、テンプレートに{{}}を使用すると変数を埋め込むことができ、{{ 変数 | XXX }} パイプ(|)でつなげることで、XXXに適用したPipeを適用することが出来ます。

自身のブログでパイプについて記載した記事があるのでよろしければご参照下さい。

https://www.multispots.net/angular-pipe/

以下公式ドキュメントでもPipeを使用して日時、通貨単位、パーセント単位がそれぞれ変換される仕組みが記載されいます。

https://angular.jp/guide/pipes

Angularのカスタムパイプ

カスタムパイプはDatePipe(日付を変換するパイプ)やCurrencyPipe(通貨を変換するパイプ)など標準で準備されているパイプでは扱うことのできない、独自のフォーマットを変換してカプセル化するために使用します。


カスタムパイプの雛形

まずは公式ドキュメントの内容を参考に、カスタムパイプを使用ための雛形を作成していきます。

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'exponentialStrength' })
export class ExponentialStrengthPipe implements PipeTransform {

   transform(value: number, exponent = 1): number {
       return Math.pow(value, exponent);
   }

}

カスタムパイプを使用する為に、PipeTransformインターフェイスを使用します。
PipeTransformインターフェイスはTransformメゾットを呼び出し、メゾットに与えられた引数を元に値を条件に基づいた変更してくれます。第二引数はパイプに渡したい値を任意に指定することが出来ます。

またPipeデコレータで指定している{ name: 'exponentialStrength' }はテンプレートでパイプを呼び出す際に使用するパイプ名となります。{ 文字列 | パイプ名 }形式で記載します。

import { Component } from '@angular/core';

@Component({
  selector: 'app-power-booster',
  template: `
    <h2>Power Booster</h2>
    <p>power boost: {{ 2 | exponentialStrength: 10 }}</p>
  `
})
export class PowerBoosterComponent { }

データを変換したいところにPipeデコレータで指定した「exponentialStrength」をパイプで繋げます。
Math.pow()関数を使用することで、第一引数(value)をexponent 乗した値、つまり、baseexponent の値に変換することが出来ます。今回はvalueに2の値を渡しているため、2の10乗された値が表示されます。

Power Booster
power boost: 1024


CurrencyPipeを利用したカスタムパイプ

次に通貨単位を変換する、CurrencyPipeを使用して通貨によって表示される単位を条件分岐させたいと思います。

CurrencyPipeは数値を通貨単位に変換してくれるフォマットです。

構文

{{ value_expression | currency [ : currencyCode [ : display [ : digitsInfo [ : locale ] ] ] ] }}

https://angular.jp/api/common/CurrencyPipe

CurrencyPipeを継承して、実装してみます。今回は渡されたcurrencyCode(JPYやKRW)によって、表示させる通貨単位を変更するようswitchで条件分岐させます。

displayは通貨単位のフォーマットを変更するインジケーターでdisplayがcodeの場合はUSD、symbolの場合は「$」となります。
この場合、通貨単位が「JPY」もしくは「KRW」の時にdisplayがsymbol隣、それ以外の通貨単位はcodeとなります。

import { CurrencyPipe } from '@angular/common';
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'customCurrency' })
export class CustomCurrencyPipe extends CurrencyPipe implements PipeTransform {

  transform(
    value: number | string,
    currencyCode?: string,
    display?: 'code' | 'symbol' | 'symbol-narrow' | string | boolean,
  ): any {

      switch (currencyCode) {
        case 'JPY':
        case 'KRW':
          display = 'symbol';
          break;
        default:
          display = 'code';
          break;
      }

    return super.transform(value, currencyCode, display);
  }

}


カスタムパイプのテスト方法

せっかくなので、Jestのテストコードも記載してみます。

import { CustomCurrencyPipe } from '../customCurrencyPipe';

describe('CustomCurrencyPipe ', () => {
    const testPipe = new CustomCurrencyPipe ();
    test('CustomCurrencyPipe', () => {
        expect(testPipe.transform('JPY')).toBe('¥');
     });
  });

これでカスタムパイプが正しく動作しているか確認できます。

以上となります。