Changeノードを制すものがNode-REDを制す

## 概要

タイトルは大げさですが、Node-REDを使ってると大半がJSONのプロパティをゴニョゴニョすることが多いため、Changeノードを使い倒すことで極力コーディングを減らすことが解りやすく再利用しやすいFlowを作るコツだと思います。

## Flowを流れるデータの理解

念のためFlowを流れるデータを理解するため復習しておきます。

まずは、Injectノードを置いて以下のように`msg.payload`に"ペイロード"という文字列が流れるように設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/5b81b8f1-4c45-d75f-d54b-7fb173293575.png)

次にDebugノードを置いて以下のようにOutputを`complete msg object`を選択します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/5a6f1212-007c-3a0c-0d74-eb3bf7f31d70.png)

2つのノードをつないでワイヤーでつないでInjectノードのスイッチをクリックすると以下のようにDebugに`msg`全体の内容が表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/a587bdec-4008-3649-e21d-ba2549ef84d1.png)

これでFlowを流れるデータが基本的に以下のような構造になっていることが理解できます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/a5c216df-c020-4850-bb45-2d36a4062552.png)

## Changeノードの"Set"を理解する

続いて以下のようにInjectノードとDebugノードの中間にChangeノードを配置します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/01cad06d-8683-12d7-ac55-0dc677bde378.png)

次にChangeノードを以下のように設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/05a37f81-539e-4215-fbc0-4e35cae0116a.png)

これを実行すると以下のように`msg.payload`の内容が"ペイロード"という文字列から"ペイロール"という文字列に書き換わりました。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/f90fadd9-9284-c65b-f0ea-89c0db8419cd.png)

つまり、Changeノードの"Set"とは以下のようなことですね。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/2021b924-164c-f66f-fdea-5c512ac19672.png)

試しに以下のようにすると`msg._msgid`の値が`msg.payload`にコピーされます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/64554149-5bf7-85be-bdd0-9bde26941a67.png)

コピーされました。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/117e7c12-89b3-a211-3947-c82856e83dec.png)

新しいプロパティを作成することも可能です。以下のように設定してみてください。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/a974223d-9e66-9293-d720-ab6661fee9e5.png)

以下のように新しく`msg.new_property`というプロパティに`msg.payload`の値である"ペイロード"という文字列が入っています。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/01f15a87-ade2-dc75-dfa8-f56ac9946553.png)

## Changeノードの"Move"を理解する

上記の通り"Set"はコピーでしたがコピー元の値を残したくない場合は"Move"を使います。ただ、ややこしいのが移動元と先が上下反転することです（これが正しいかどうかはよくわかりません）

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/2c87631b-b449-39cb-44c4-65903656d3da.png)

以下のようにコピー元（`msg.payload`）が消滅し移動先に移ります。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/0b96fae7-d6e2-4ea7-7f80-91c822b6acfd.png)

## Changeノードの"Change"を理解する

次に"Change"です。以下のように設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/4f877e7b-8ee7-8acb-4905-77e3e8635dea.png)

すると、対象のプロパティの値を置き換える感じです。要は`replace`ですね。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/3773059e-7b02-ca9a-83f7-1a2a4f44c3dc.png)

デフォルトで再帰的な置き換えのようです。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/9261618f-c0bc-8459-fe50-a398f2a978e6.png)

## Changeノードの"Delete"を理解する

次に"Delete"ですが以下のように設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/ba064f7d-46c0-a020-0327-7e159c0339bc.png)

すると指定したプロパティが消滅します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/f7fbdcdd-3ce4-0971-07c3-d660fb49d2c4.png)

## 複数ルールを理解する

以下のように"Set"設定をします。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/2a33e242-16d2-e03d-090a-b512cfbad542.png)

`msg.aaa.bbb`プロパティへ値がコピーされました。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/41835e4e-0ce5-4ed3-2b5c-7f2262917959.png)

続いて以下のように"Change"設定のノードを後続置きます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/d0db17e0-f40e-368e-0a69-08c4df8c49d9.png)

"Change"の設定は以下です。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/3d3cf143-fbc9-8431-7cdb-f7b05a9b5625.png)

これを実行すると以下のように"Set"設定のノードだけを通過した結果と"Change"設定のノードも通過した結果の2つが得られます。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/df52831f-fef1-0857-add6-f493954e40ca.png)

各ノードを通過したデータが欲しい場合は上記のようにしますが"Set"して"Change"したものだけが欲しい場合は以下のようにまとめて設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/65356c0d-d0b5-923c-dd7f-ba1e9b14b36b.png)

処理の順序は設定上でルール設定している上から下の順に実行されますので以下のような結果になります。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/e1b7a7cc-61a7-1063-b846-2abe5e4a587b.png)

## まとめ

Changeノードを使えばデータ変換の多くのことは実現できると思います。Functionノードでプロパティの操作や文字列操作をするケースが発生したら、まずChangeノードで実現できないか試みるようにしてみるとFlowからコーディングが劇的に減ると思います。是非、Changeノードを使い倒して極力コーディングしないFlowを作ってみてください！

## おまけ

プロパティ操作ができるのは`msg`だけでなく以下のように`flow`や`global`も可能です。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/e6eb6942-9e34-e93d-5208-5ac3c4806bc4.png)