0

I am trying to implement dependent external selects inside a modal but I am having problems passing the state of the first dropdown to the second. I can see the state I need inside the app.action listener but I am not getting the same state inside the app.options listener.

body.view.state inside app.action("case_types"). I specifically need the case_create_case_type_block state.

  "state": {
    "values": {
      "case_create_user_select_block": {
        "case_create_selected_user": {
          "type": "users_select",
          "selected_user": "U01R3AE65GE"
        }
      },
      "case_create_case_type_block": {
        "case_types": {
          "type": "external_select",
          "selected_option": {
            "text": { "type": "plain_text", "text": "Incident", "emoji": true },
            "value": "Incident"
          }
        }
      },
      "case_create_case_subtype_block": {
        "case_subtypes": { "type": "external_select", "selected_option": null }
      },
      "case_create_case_owner_block": {
        "case_owners": { "type": "external_select", "selected_option": null }
      },
      "case_create_subject_block": {
        "case_create_case_subject": {
          "type": "plain_text_input",
          "value": null
        }
      },
      "case_create_description_block": {
        "case_create_case_description": {
          "type": "plain_text_input",
          "value": null
        }
      }
    }
  },

body.view.state inside app.options("case_subtypes")

  "state": {
    "values": {
      "case_create_user_select_block": {
        "case_create_selected_user": {
          "type": "users_select",
          "selected_user": "U01R3AE65GE"
        }
      }
    }
  },

I did also try to update the view myself hoping it would update the state variables inside app.action({ action_id: "case_types" })

    //need to update view with new values
    try {
      // Call views.update with the built-in client
      const result = await client.views.update({
        // Pass the view_id
        view_id: body.view.id,
        // Pass the current hash to avoid race conditions
        hash: body.view.hash,
      });
      console.log("Case Type View Update result:");
      console.log(JSON.stringify(result));

      //await ack();
    } catch (error) {
      console.error(error);
      //await ack();
    }
Crash667
  • 343
  • 2
  • 16

1 Answers1

0

I ended up posting this on the github issues page for slack bolt. This was a bug that will fixed in a future release. Below is the workaround using private metadata to hold the state to check for future dependent dropdowns.

// Action handler for case type
app.action('case_type_action_id', async ({ ack, body, client }) => {
  try {
    // Create a copy of the modal view template and update the private metadata
    // with the selected case type from the first external select
    const viewTemplate = JSON.parse(JSON.stringify(modalViewTemplate))
    viewTemplate.private_metadata = JSON.stringify({
      case_type: body.view.state.values['case_type_block_id']['case_type_action_id'].selected_option.value,
    });

    // Call views.update with the built-in client
    const result = await client.views.update({
      // Pass the view_id
      view_id: body.view.id,
      // Pass the current hash to avoid race conditions
      hash: body.view.hash,
      // Pass the updated view
      view: viewTemplate,
    });
    console.log(JSON.stringify(result, 0, 2));
  } catch (error) {
    console.error(error);
  }

  await ack();
});

// Options handler for case subtype
app.options('case_subtype_action_id', async ({ body, options, ack }) => {
  try {
    // Get the private metadata that stores the selected case type
    const privateMetadata = JSON.parse(body.view.private_metadata);

    // Continue to render the case subtype options based on the case type
    // ...
  } catch (error) {
    console.error(error);
  }
});

See the full explaination here: https://github.com/slackapi/bolt-js/issues/1146

Crash667
  • 343
  • 2
  • 16