こんにちは、@kotamatです。
昨日Babel7がリリースされましたね🎉
https://babeljs.io/blog/2018/08/27/7.0.0
Babel6から3年かかってのリリースです。コントリビューターの方々お疲れ様でした。
パッケージ名からの破壊的変更が入っていますが、babelのupgrade用スクリプトが用意されているので、手軽にupgradeすることができます(執筆時点だと、beta版までしかあげられませんが‥)
Babel7のリリースに伴い、TS39の新しいシンタクスがサポートされ、その中でもStage1のOptional Chainingが、Laravelのエラーハンドリングにとても相性がいいので紹介させていただきます。
Laravelのバリデーションエラー
Laravel側でFormRequestを用いて下記のようなバリデーションルールを実装した場合、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class StoreRelationRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'address.prefecture' =>['required', 'string'],
'address.zipcode' =>['required', 'integer'],
'staff.*.id' =>['required', 'integer'],
'staff.*.name' =>['required', 'string'],
];
}
}
|
staffの0, 1がバリデーションに引っかかった場合、下記のようなバリデーションメッセージが帰ってきます
1
2
3
4
5
6
7
8
| {
"address.prefecture": ["The prefecture field is required."],
"address.zipcode": ["The zipcode field is required."],
"staff.0.id": ["The id field is required."],
"staff.0.name": ["The name field is required."],
"staff.1.id": ["The id field is required."],
"staff.1.name": ["The name field is required."]
}
|
このままでは、フロント側では扱いづらいので、フロント側で扱いやすい形に整形します
reno-shelter/convert-laravel-validationを使うと、上記メッセージは下記のように修正されます
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| {
address: {
prefecture: ['The prefecture field is required.'],
zipcode: ['The zipcode field is required.'],
},
staff: {
0: {
name: ['The name field is required.'],
id: ['The id field is required.'],
},
1: {
name: ['The name field is required.'],
id: ['The id field is required.'],
},
},
}
|
Optional Chainingでメッセージを取り扱う
上記オブジェクトでは、例えば、address.*系のエラーがない場合は、当然ながら参照できない形になってしまうため、メッセージ表示部分で存在可否のチェックを行わないとundefined indexのFatal Errorが発生してしまいます。
そこで便利なのがOptionalChainingです。
Optional chainingの仕組み
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| const obj = {
foo: {
bar: {
baz: 42,
},
},
};
const baz = obj?.foo?.bar?.baz; // 42
const safe = obj?.qux?.baz; // undefined
// Optional chaining and normal chaining can be intermixed
obj?.foo.bar?.baz; // Only access `foo` if `obj` exists, and `baz` if
// `bar` exists
|
このように、存在しないパラメータがチェーンの途中にあるばあいは、そこでundefinedを返し、ランタイムでのエラーを防ぐ事ができます。
1
2
3
4
5
6
| <template>
<div>
<input v-model="address.prefecture" />
<error v-for="(msg, key) in error?.address?.prefecture || []" :key="key" :msg="msg"/>
</div>
</template>
|
上記のようにテンプレート内でerror?.address?.prefecture
とすることによって、もしerror
, error.address
, error.address.prefecture
がそれぞれ存在しなかったとしても問題なく実行されるため、無駄にif文で分岐して処理を複雑にする必要はなくなります。
インストール方法
babel7が入っている前提で話をすすめます。babel6以前からのアップデートはbabelupdateを参考にしてください。
まずはyarn (or npm)でプラグインをインストールし、
1
| yarn add @babel/plugin-proposal-optional-chaining |
.babelrcでpluginの設定をするだけです、
1
2
3
| {
"plugins": ["@babel/plugin-proposal-optional-chaining"]
}
|
Nuxt.jsであればnuxt.config.jsに下記のように記載します
1
2
3
4
5
6
7
| export default {
build: {
babel: {
plugins: ['@babel/plugin-proposal-optional-chaining']
}
}
}
|
まとめ
Babel7で新たに入ったOptionalChainingの紹介をさせていただきました。まだProposalの段階なので変更が入る可能性はありますが、より実装にフォーカスしたコーディングができるようになるので、是非導入してみてください!
Author
kotamat
LastMod
2019-11-04
(5d46beb)