kintoneのグループフィールド開閉がArray.map() で上手く行かないので forEach() を使ったら上手く行った話し

kintoneのグループフィールドをPC版では開いておきたいけど、モバイルの時は初期状態で閉じておきたいとの要望があり、フォーム設定情報から取得した一覧に対してグループフィールドの開閉をしたいと思い試してみました。

# 試してみた

## 1. kintone.events.on の イベントハンドラ内で直接書く

一般的な書き方。もちろん問題無く動きます。

```javascript
    kintone.events.on('mobile.app.record.detail.show', async function(event) {
        try {
            kintone.mobile.app.record.setGroupFieldOpen('group1', false);
```

## 2. Array.map() のコールバック内に書く

動きませんでした。

```javascript
    kintone.events.on('mobile.app.record.detail.show', async function(event) {
        try {
            const params = {'app': await kintone.mobile.app.getId()};
            const response = await kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', params);
            // 指定したフィールドタイプを配列として取得する
            const fields = getFields(response, 'GROUP');
            // mapを利用
            fields.map((field) => {
                kintone.mobile.app.record.setGroupFieldOpen(field.code, 'false');
            });
```

## 3. forEach のコールバック内に書く

動きました。

```javascript
    kintone.events.on('mobile.app.record.detail.show', async function(event) {
        try {
            const params = {'app': await kintone.mobile.app.getId()};
            const response = await kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', params);
            // 指定したフィールドタイプを配列として取得する
            const fields = getFields(response, 'GROUP');
            // forEachを利用
            fields.forEach(field => {kintone.mobile.app.record.setGroupFieldOpen(field.code, false)});
```

## 4. forEach() 部分を関数に書く

動きませんでした。

```javascript
(function() {
    'use strict';
    var setGroupFieldsOpen = (fields, flug) => {
        fields.forEach(field => {kintone.mobile.app.record.setGroupFieldOpen(field.code, flug)});
    };
    kintone.events.on('mobile.app.record.detail.show', async function(event) {
        try {
            const params = {'app': await kintone.mobile.app.getId()};
            const response = await kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', params);
            // 指定したフィールドタイプを配列として取得する
            const fields = getFields(response, 'GROUP');
            setGroupFieldsOpen(fields, 'false');
        } catch (error) {
            console.log(error);
        };
        return event;
    });
```

## 5. for...of を利用する

OK。

```
    const setGroupFieldsOpenForOf = (fields, flug) => {
        for(const field of fields) {
          kintone.mobile.app.record.setGroupFieldOpen(field.code, flug);
        }
    };
```

# 結論

## 追記
2022-04-11

kintoneでIEがサポートから外れたので、これからは for...of を積極的に使うで良いかもしれません。
今回のケースのように、新しく配列を返す必要がなければ、map()を使う必要性もないですし。

---

* Array.map() で上手くいかない時は forEach() を使ってみる。
* forEach()部分を関数にすると動かない。

動かない理由は良く分からないのですが、まあ良しとします。
変数のスコープ？が影響するのか。。。
kintone JS API は関数によりますが、素直に kintone.events.on 内で書いた方が良いかもしれませんね。


# サンプルコード

参考までにコードを載せておきます。

```javascript

(function() {
    'use strict';
    kintone.events.on('mobile.app.record.detail.show', async function(event) {
        try {
            const params = {'app': await kintone.mobile.app.getId()};
            // フォーム情報の取得
            const response = await kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', params);
            // 指定したフィールドタイプを配列として取得する
            const fields = getFields(response, 'GROUP');
            fields.forEach(field => {kintone.mobile.app.record.setGroupFieldOpen(field.code, false)});
        } catch (error) {
            console.log(error);
        };
        return event;
    });

    function getFields (fields, fieldType) {
        let result = [];
        try {
            const values = Object.values(fields.properties);
            if (fieldType) {
                values.map((field) => {
                    if (field.type === fieldType) {
                        result.push(field);
                    }
                });
            } else {
                result = values;
            }
            return result;
        } catch (error) {
            return error;
        }
    }
})();
```

# 参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of