Hi all 馃憢,
Here's the flow of my app:
1) The user mention the bot in any channel.
2) The app replies with a welcome message and options (including "Create" a new item)
3) If the user clicks 'create', the app opens a modal with a form.
4) If there's no error, the app replaces the message from .2 with a feedback/overview about the item created.
I'm struggling to validate the form.
First, I'm not 100% what's the proper method to listen for submit: app.action with callback_id or app.view?
If I use app.action it says "An incoming event was not acknowledged before the timeout. Ensure that the ack() argument is called in your listeners" in the console and "We had some trouble connecting. Try again?" in the modal's header.
app.action({ callback_id: 'create' }, ({ ack }) => ack({ errors }))
If I use app.view, the callback is fired but I can only reply with ack(), with no error:
app.view('create', ({ ack }) => ack({ errors }));
Once the user submit the view, using the previous listener, the modal shows: "We had some trouble connecting. Try again?" but faster, before the 3 seconds limit. I'm assuming the ack sent the response.
On top of all that: I have two rules to validate the form, that could be "onBlur/onChange":
a) there a input/plain text that must to be unique (need to check the database)
b) there a multi_user_select that must to have 2+ items.
I know that radio button supports this kind of 'onChange' validations. Input and selects also supports it?
x in one of the [ ])x in each of the [ ])Once the user submit the view, using the previous listener, the modal shows: "We had some trouble connecting. Try again?" but faster, before the 3 seconds limit. I'm assuming the ack sent the response.
Regarding the view_submission response, I think you need to put response_action as well.
https://api.slack.com/surfaces/modals/using#displaying_errors
ack({
response_action: "errors",
errors: errors
});
There is no way to return errors towards block_actions (that means the events handled by app.action in Bolt). Instead, for some use cases, updating the modal with some additional information (= error messages) by appending more blocks/elements may work. It's fairly simple as below:
app.action('action-id', async ({ ack, client }) => { // bolt 1.6.0
await client.views.update({
view_id: body.view.id,
view: buildViewWithErrorMessages(),
hash: body.view.hash
});
ack();
});
a) there a input/plain text that must to be unique (need to check the database)
b) there a multi_user_select that must to have 2+ items.
This is not an interesting answer but I think the most straightforward way for implementing your custom validation rules would be having all the inputs as input-typed blocks and validating all of them at a time in a view_submission handler (app.view(callback-id, fn)).
I know that radio button supports this kind of 'onChange' validations. Input and selects also supports it?
Did you mean confirm objects? If so, others also support it. You can find the supported elements by searching this page by "confirm". That said, as you may know, the things the confirm can do is limited.
If you meant other things, I would like to know more about what you mentioned is.
Did you mean confirm objects?
Not really. When we have radios buttons, they fire an event when the user change select another option. Example here. I guess the purpose is to be able to update the view, but could also be useful to validate a single field async.
Thanks. I do understand it's more powerful if we have such a single filed validation but unfortunately, it doesn't exist yet. As you guessed, currently block_actions on a modal is supposed to be used for updating the modal.
@Falci Please let me know if you have something further to ask or discuss here. Otherwise, allow me to close this issue.
I empathize with your inconvenience with block_actions. However, the Bolt team doesn't have any actions to take until the Slack Platform introduces new features related to this. 馃檹
Sorry by my delay. It worked.
ack({
response_action: 'errors',
errors: {
field: 'error'
}
});
Most helpful comment
Sorry by my delay. It worked.