AlecAivazis / survey

A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
MIT License
4.07k stars 349 forks source link

Add TransformInteger feature #460

Closed dilaragorum closed 1 year ago

dilaragorum commented 1 year ago

When users want to use survey.Ask method which can return as map[string]interface{}, they may need an integer transformer that converts string results to an integer.

For example, if the survey.Question is defined as shown below

{
    Name:      "Age",
    Prompt:    &survey.Input{Message: "Age:"},
    Validate:  survey.Required,
},

and ask it like

answers := make(map[string]interface{})
if err := survey.Ask(qs, &answers); err != nil {
    panic(err)
}

Age field comes as interface{} | string type

Screen Shot 2022-10-16 at 14 00 55

In order to use this field as Integer, it is needed to use strconv.Atoi method so I wrote down a ready-to-use Transformer.

They use this transformer as

{
    Name:      "Age",
    Prompt:    &survey.Input{Message: "Age:"},
    Validate:  survey.Required,
        Transform: survey.TransformInteger,
},

Age field comes as interface {} | int type

Screen Shot 2022-10-16 at 14 05 27
mislav commented 1 year ago

Hi, thank you for the contribution, but Survey can already convert the entered value into an integer if it's storing the value into a variable or struct field that is of int type. https://github.com/AlecAivazis/survey/issues/388#issuecomment-1280760228

If you have multiple questions and want to store the answers into a single answers object, use a struct instead of map[string]interface{}. This will also be easier to work with in the rest of your program:

var answers struct {
  Age int
}

The downside of the Transformer approach that you have suggested in your PR is that it doesn't throw errors on invalid integer values and just returns 0 instead. The approach outlined above will correctly handle invalid inputs by erroring out.