Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 157: trigger onConfirm after set state #169

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

samtsai
Copy link
Contributor

@samtsai samtsai commented Jun 14, 2017

onConfirm is currently triggered before setState is called,
to keep proper state with what is sent to onConfirm, setState
should be called then onConfirm.

This is to resolve #157

@samtsai samtsai force-pushed the issue-157-trigger-confirm-after-value-set branch from 2b24f4f to 5344b08 Compare June 14, 2017 17:16
@samtsai
Copy link
Contributor Author

samtsai commented Jun 14, 2017

Have some linting errors, let me fix

@samtsai samtsai force-pushed the issue-157-trigger-confirm-after-value-set branch from 5344b08 to 62022fc Compare June 14, 2017 19:00
@@ -165,7 +164,7 @@ export default class Autocomplete extends Component {
menuOpen: newState.menuOpen || false,
query: newQuery,
selected: null
})
}, this.props.confirmOnBlur ? this.props.onConfirm(newQuery) : null)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tvararu I wasn't quite sure how the selected property was being used so I opted to just send newQuery. During testing, selected was -1 so option[selected] was not returning what I expected.

Copy link
Contributor

@tvararu tvararu Jun 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted to just send newQuery

👍 That's fine. options[selected] was weird given that newQuery exists in the same scope.

The second argument to setState should be a callback function. You're passing the result of the onConfirm() invocation. So your code (when this.props.confirmOnBlur === true) at runtime is:

this.setState({
  focused: null,
  menuOpen: newState.menuOpen || false,
  query: newQuery,
  selected: null
}, undefined)

With the added side effect of running onConfirm in order to produce the undefined argument for setState, which shouldn't actually solve the underlying issue (if it did, that's curious).

Instead you want this (added () =>):

this.setState({
  focused: null,
  menuOpen: newState.menuOpen || false,
  query: newQuery,
  selected: null
}, () => this.props.confirmOnBlur ? this.props.onConfirm(newQuery) : null)

Also apply the same change to the other place where this is used. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options[selected] was weird given that newQuery exists in the same scope.

Actually, disregard what I said. It should be options[selected]. options[-1] returning undefined is correct behaviour. In which tests did you find this to be unexpected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @tvararu, I will correct the callback application, but as far as sending options[selected] to onConfirm, wouldn't that be misleading? I thought onConfirm is meant to receive the selected query, in which case options[-1] was giving undefined.

What I mean is, in normal usage the selected property was not being updated in the state in all cases or would come back as -1. I was just using any of the example Autocompletes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samtsai it's meant to receive the selected option which can be an object. query is just a printable string that gets inlined as part of the input. For most usecases these two concepts are identical, but the autocomplete does support more advanced use cases using the templates.inputValue option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok makes sense, I'll need to take a look at this a little longer, going to be on vacation rest of this weekend, so I'll pick it up next week.

Likely, I'll want to update my tests to reflect your comments.

@@ -165,7 +164,7 @@ export default class Autocomplete extends Component {
menuOpen: newState.menuOpen || false,
query: newQuery,
selected: null
})
}, this.props.confirmOnBlur ? this.props.onConfirm(newQuery) : null)
Copy link
Contributor

@tvararu tvararu Jun 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted to just send newQuery

👍 That's fine. options[selected] was weird given that newQuery exists in the same scope.

The second argument to setState should be a callback function. You're passing the result of the onConfirm() invocation. So your code (when this.props.confirmOnBlur === true) at runtime is:

this.setState({
  focused: null,
  menuOpen: newState.menuOpen || false,
  query: newQuery,
  selected: null
}, undefined)

With the added side effect of running onConfirm in order to produce the undefined argument for setState, which shouldn't actually solve the underlying issue (if it did, that's curious).

Instead you want this (added () =>):

this.setState({
  focused: null,
  menuOpen: newState.menuOpen || false,
  query: newQuery,
  selected: null
}, () => this.props.confirmOnBlur ? this.props.onConfirm(newQuery) : null)

Also apply the same change to the other place where this is used. :)

@tvararu
Copy link
Contributor

tvararu commented Jun 15, 2017

See comment, looks good otherwise. 👍

@samtsai samtsai force-pushed the issue-157-trigger-confirm-after-value-set branch from 62022fc to 2c70526 Compare June 15, 2017 16:11
Copy link
Contributor

@tvararu tvararu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few changes, thanks for coming back to this. 👍

Looks much cleaner!

if (this.props.confirmOnBlur) {
newQuery = newState.query || query
this.props.onConfirm(options[selected])
setStateCallback = this.props.onConfirm(options[selected])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

setStateCallback = () => this.props.onConfirm(options[selected]) 

this.setState({
focused: -1,
menuOpen: false,
query: newQuery,
selected: -1
})
}, this.props.onConfirm(selectedOption))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

}, () => this.props.onConfirm(selectedOption))

@NickColley
Copy link
Contributor

NickColley commented Aug 29, 2017

Should this be documented somewhere?

Edit: Actually, I've reread it this does not introduce anything new. 👍

@samtsai samtsai force-pushed the issue-157-trigger-confirm-after-value-set branch from 2c70526 to ad7fc95 Compare August 29, 2017 13:36
@tedw
Copy link

tedw commented Feb 22, 2019

Any update on this? Thanks!

@romaricpascal romaricpascal added this to the After next milestone Jan 11, 2024
Let the state be set with updated value then trigger
`onConfirm`
@colinrotherham colinrotherham force-pushed the issue-157-trigger-confirm-after-value-set branch from ad7fc95 to d2e80b9 Compare January 17, 2024 13:31
@colinrotherham
Copy link
Contributor

I've rebased this one with main to help us review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

onConfirm function is triggered before the auto selected option is set as the value of the input
6 participants