unlock-protocol / unlock

Ʉnlock is a protocol for memberships built on a blockchain.
https://unlock-protocol.com
MIT License
839 stars 248 forks source link

Feature request: ability to set and reset many errors with one redux action #992

Closed cellog closed 5 years ago

cellog commented 5 years ago

Feature request Background

This challenge is currently a blocker for another issue.

For error processing in the Creator Lock Form (#797) I have been working on a PR to implement this. In the process of doing this, I have encountered (or imagined in the case of #3) these possible scenarios:

Scenario 1: User triggers multiple errors This happens when the user resets 2 form fields to empty, for example

Scenario 2: User triggers an error, and then replaces it with another error This happens when the user deletes the key expiration and replaces it by pasting in an invalid value. The "key expiration is missing" error is replaced by "key expiration is invalid"

Scenario 3: User is editing the form, and an unrelated error condition occurs which must be displayed This could happen if, for example, the user is editing and the internet goes down, removing access to the blockchain or to locksmith

Scenario 1 is handled by implementing multiple errors #978 Scenario 2 could result in 2 errors being displayed, 1 of which is invalid and is not yet handled Scenario 3 could result in the external error being cleared, because the form resets all errors when it is valid

Proposed Solution I would like to add a new action, bulkSetErrors which accepts 2 arrays. The first will be an array of errors to set, and the second an array of errors to clear. The reducer will check for any errors that need to be set, and clear any that need to be cleared, leaving all others intact. usage like:

bulkSetErrors([FORM_LOCK_NAME_MISSING], [/* form errors that are not currently set */])

This action would provide a sandboxed state change to the error list. Only errors explicitly mentioned would be set or reset.

Other solutions considered

Currently, the only error API is setError, which is called with null to clear all existing errors. One solution is to add a resetError action, which would clear an individual error.

This requires the creator lock form to trigger a setError or resetError action on validation of each form field, and will generate 7 redux actions on every keystroke. This has the disadvantage of being quite slow on a mobile device and could result in dropped keystrokes.

Alternatively, the error state could be provided to CreatorLockForm and used to only trigger a resetError or setError if the error is not currently set. This has the disadvantage of tightly coupling the creator lock form to the internal error representation.

Why the proposed solution is probably the best option The error set/reset actions will be triggered quite often in form editing (every keystroke) and to avoid re-render hell, we will need an efficient solution.

Possible future enhancements If the form ends up still be unresponsive, we can implement a debouncing delay of 100ms before triggering a new action. With this implementation, that will be trivial. With multiple triggers of setError/resetError it becomes quite complex to manage the state.

In addition, a possible enhancement would be to memoize existing error state and compare to new state, avoiding triggering a new bulkSetErrors if state has not changed. This requires passing in the error state to CreatorLockForm so is not part of this initial design, and would only be implemented if performance becomes a real issue.

Conclusion Before I implement this, I'd like feedback from @julien51 and anyone else who has a strong opinion on the question.

Once this question is settled, #797 will be ready for an initial PR

julien51 commented 5 years ago

Thanks for this detailed proposal.

Before weighing further I think I need to understand better. For now, my understanding is that on CreatorLockForm we invoke validate every time a field is changed. My understanding is that you would want to add that error to the redux store immediately. Is that correct?

I'd want first to challenge that assumption. I think that this may appear to be very 'obnoxious'. I also worry that this means the all UI will go down/up every time because the 'error' banner will take some space at the top of the form?

I think what we should do is only add events to the redux store when the user hits submit. Then we can show what is wrong with their form in more details. This would also solve the current issue where nothing happens when the user hits submit on a non valid form.

I agree that just having a red background might be not quite enough and we may want to provide more info, but I am not sure that the best place to do that is at the top of the form? (at least for now I think all our fields are fairly self-describing and a user would probably know right away what is wrong?)

I also think this is how most forms work online? They show you actual errors only when submitting and have an indication of what they expect underneath it?

What do you think about that?

If we go down this route, I think things will probably be much simpler. We then can expect the user to either close each individual error, or to change the problematic values so that when they submit, we unset all errors (and/or add new ones)

cellog commented 5 years ago

Hi,

Yes, that sounds good. This action would still be necessary at that point, and also easy to generate, as we can store it in the component state, and only propagate it on form submit.

Greg

On Sun, Jan 13, 2019 at 7:44 PM Julien Genestoux notifications@github.com wrote:

Thanks for this detailed proposal.

Before weighing further I think I need to understand better. For now, my understanding is that on CreatorLockForm we invoke validate every time a field is changed. My understanding is that you would want to add that error to the redux store immediately. Is that correct?

I'd want first to challenge that assumption. I think that this may appear to be very 'obnoxious'. I also worry that this means the all UI will go down/up every time because the 'error' banner will take some space at the top of the form?

I think what we should do is only add events to the redux store when the user hits submit. Then we can show what is wrong with their form in more details. This would also solve the current issue where nothing happens when the user hits submit on a non valid form.

I agree that just having a red background might be not quite enough and we may want to provide more info, but I am not sure that the best place to do that is at the top of the form? (at least for now I think all our fields are fairly self-describing and a user would probably know right away what is wrong?)

I also think this is how most forms work online? They show you actual errors only when submitting and have an indication of what they expect underneath it?

What do you think about that?

If we go down this route, I think things will probably be much simpler. We then can expect the user to either close each individual error, or to change the problematic values so that when they submit, we unset all errors (and/or add new ones)

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/unlock-protocol/unlock/issues/992#issuecomment-453880895, or mute the thread https://github.com/notifications/unsubscribe-auth/AAF_ynNOx2EE3PM2h3P2PcZfFM5esA64ks5vC9LYgaJpZM4Z81bJ .

-- https://twitter.com/gregcello Unlock https://unlock-protocol.com/ The web's new business model