Closed rdmulford closed 2 years ago
I think if answers
already has a valid value for the key, asking for one should be skipped.
Something like this should go straight through without any prompts, the name should become titlecased.
name := "hello world"
email := "hello@example.com"
userConfig := config.UserConfig{
Name: name,
Email: email,
}
questions := []*survey.Question{
{
Name: "name",
Prompt: &survey.Input{Message: "Name"},
Validate: validateName,
Transform: survey.Title,
},
{
Name: "email",
Prompt: &survey.Input{Message: "Email"},
Validate: validateEmail,
},
}
err := survey.Ask(questions, &userConfig)
I think if
answers
already has a valid value for the key, asking for one should be skipped.
Define valid value. nil
, 0
, ""
are all valid values in golang.
I stumbled across this case earlier when working on a CLI that I wanted to have some power user flags. For example, something like: ./cli create --name MyInput
could help with cases where you would normally be prompted to enter a name.
My immediate thought was maybe adding a check before the prompt that checks if there's already an answer for the question, and if that answer passes validations, to skip the prompt portion. But then I can see how that opens up a whole other class of questions -- ie. How would a validation failure look? What if you just want pre-filled answers to be suggested defaults? What if you want them to skip validations?
Ultimately, it felt like I was trying to shoehorn my own business logic into the package, so I ended up managing those inputs on my end.
Simple Example:
var name string
func main() {
...
if len(name) > 0 {
fmt.Println(fmt.Sprintf("Name: %s", name))
answers.Name = name
...
} else {
// questionsWithoutName is the array of survey.Question structs, with the Name question filtered out
err := survey.Ask(questionsWithoutName, &answers)
...
}
}
If you're running validations or transformations, things are likely a bit more complicated, but I was just working on something tiny, so this worked well enough.
I also want to use a default and suggestions based on previous answers.
This would be very welcome, the syntax suggested seems reasonable.
Thanks everyone for the suggestions!
If your application needs subsequent questions to react to the answers of previous questions, you should go with multiple Asks:
if err := survey.Ask(questions1, &answers); err != nil {
panic(err)
}
if err := survey.Ask(questions2, &answers); err != nil {
panic(err)
}
That way you have absolute freedom to implement whichever logic you'd like.
Note that the Default
property of Survey inputs is a Go value, not a reference. The provided value will be static and cannot change dynamically between survey prompts.
When defining multiple questions in one block, it would be great if you could set the default value for one question equal to the answer of a previously answered question. See example below for more clarity on the issue.
Environments Tested
OS: MacOS Terminal: iTerm2 Shell: zsh Version: github.com/AlecAivazis/survey/v2 v2.0.7
Example Program:
Output
Expected
I would expect the second question to display a default value of
text
.