is there a way to do a while loop for prompted input questions, bind them and have all answers available in an array?
Asked Answered
B

2

7

I am building a Yeoman generator and dependencies needed for this come from https://github.com/sboudrias/mem-fs-editor#copytplfrom-to-context-settings and https://github.com/SBoudrias/Inquirer.js/

The idea is to be able to ask the user a question and repeat the same question i.e. would you like to add another... if the user adds another then it will bind and record that answer and if the user says 'no' or hits return the prompt will stop.

I would like to then have all of the answers binded to an arrary that can be passed to another object function so that it can list out the responses as an array.

Here is the code so far... First is the prompt:

askForTest1: function () {
    if (this.type == 'foundation5') {
        var cb = this.async();

        var prompts = {
            type: 'input',
            name: 'test1',
            message: chalk.yellow('  What is your favorite movie'),
            default: 'Star Wars!'
        };

        this.prompt(prompts, function (props) {
            this.templatedata.test1 = props.test1;

            cb();
        }.bind(this));
    }
},

Then is the copyTpl object that will bind options for template builds: This is the desired output I would like to occur... and keep in mind this copy tpl lives in the same index.js file as the prompts. i.e. this template...

       this.fs.copyTpl(
              this.templatePath('/index2.html'),
              this.destinationPath('app/index2.html'),
              { title: [this.templatedata.test1-a, this.templatedata.test1-b, this.templatedata.test1-c, ...], h1: this.applicationName }
            );

as a result... a template with this code...

using

will produce this...

using foo1
using foo2

is this possible and how would I go about doing this.

Blodget answered 11/4, 2015 at 0:53 Comment(7)
Use array.push(value) to add a value to an array.Flabbergast
that's good for writing to the DOM but not the actual fool.js document. how could I get the value to write to the document.Blodget
I don't know what fool.js is, but I don't see why it would make a difference. You just asked how to put the results in an array. What you do with the array when you're done shouldn't matter.Flabbergast
Maybe I am completely not thinking of this correctly, but that array.push is pushing it to the dome. What if I want to push it to an actual array.Blodget
var foo = []; foo.push(3); will push 3 onto the array in the foo variable. I don't know of any way that this would modify the DOM.Flabbergast
sorry you are correct.. but my question becomes I need it to push to title: [array]... if the value isn't seen per se then how do I know that it is there? and will be the information I want as described above... this.templatedata.test1-a, this.templatedate.test1-b... and so on?Blodget
We're clearly not understanding each other. You need to make an executable demo that shows what you're doing. Maybe the issue is something specific to Yeoman Generator, which I don't know anything about.Flabbergast
P
4

Something like this should work for you:

function() {
    var answers = {
        times: [],
        title: undefined,
        type: undefined
    };

    function promptMe(prompt, cb) {
        self.prompt(prompt, function (props) {
            if(props.answer!= "done") {
                answers.times.push(props.time);
                promptMe(prompt, cb);
            } else {
                cb();
            }
        });
    }

    var cb = this.async(),
        self = this,
        movieTypePrompt = {
            type: 'input',
            name: 'movieType',
            message: chalk.yellow('What is your favorite type of movie?'),
            default: 'Action'
        },
        movieTitilePrompt = {
            type: 'input',
            name: 'movieTitle',
            message: chalk.yellow('What is your favorite movie?'),
            default: 'Tron: Legacy'
        }
        movieTimePrompt = {
            type: 'input',
            name: 'time',
            message: chalk.yellow('When can you watch a movie? (enter \'done\' when you are done entering times)'),
            default: '8PM'
        };

    //Prompt for movie type and title
    this.prompt([movieTypePrompt, movieTitlePrompt], function (props) {
        answers.title = props.movieTitle;
        answers.type = props.movieType;

        //Repeatedly prompt for movie times
        promptMe(moviePrompt, function() {
            console.log('done');

            cb();
        });
    }.bind(this));
}
Pyrogallol answered 22/4, 2015 at 4:27 Comment(0)
T
5

This is fairly simple programming task.

Use recursion of a method asking the question to the user. Then if the user answered "yes add more", you just call the same function again.

Something roughly like that:

initializing: function () {
  this.movies = [];
},

askMovie: function (cb) {
  cb = cb || this.async();

  var prompts = [{
      type: 'input',
      name: 'movie',
      message: chalk.yellow('  What is your favorite movie'),
      default: 'Star Wars!'
  }, {
    type: 'confirm',
    name: 'askAgain',
    message: 'ask again?'
  }];

  this.prompt(prompts, function (props) {
    this.movies.push(props.movie)
    if (props.askAgain) {
      this.askMovie(cb);
    } else {
      cb();
    }
  }.bind(this));
  }
}
Toiletry answered 19/4, 2015 at 21:1 Comment(2)
just the fact of this being async made this not too friendly i.e. why there wasn't a while loop used... which is what I initially went for. I eventually came up with something similar but I do really like your askAgain prompt... makes a lot of sense.Blodget
It's a pretty normal javascript/node.js pattern. Actions are all asynchronous, so better get used to callbacks. About recursion, that's also a pretty broad programming concept you should get familiar with; it's useful in a lot of situations.Toiletry
P
4

Something like this should work for you:

function() {
    var answers = {
        times: [],
        title: undefined,
        type: undefined
    };

    function promptMe(prompt, cb) {
        self.prompt(prompt, function (props) {
            if(props.answer!= "done") {
                answers.times.push(props.time);
                promptMe(prompt, cb);
            } else {
                cb();
            }
        });
    }

    var cb = this.async(),
        self = this,
        movieTypePrompt = {
            type: 'input',
            name: 'movieType',
            message: chalk.yellow('What is your favorite type of movie?'),
            default: 'Action'
        },
        movieTitilePrompt = {
            type: 'input',
            name: 'movieTitle',
            message: chalk.yellow('What is your favorite movie?'),
            default: 'Tron: Legacy'
        }
        movieTimePrompt = {
            type: 'input',
            name: 'time',
            message: chalk.yellow('When can you watch a movie? (enter \'done\' when you are done entering times)'),
            default: '8PM'
        };

    //Prompt for movie type and title
    this.prompt([movieTypePrompt, movieTitlePrompt], function (props) {
        answers.title = props.movieTitle;
        answers.type = props.movieType;

        //Repeatedly prompt for movie times
        promptMe(moviePrompt, function() {
            console.log('done');

            cb();
        });
    }.bind(this));
}
Pyrogallol answered 22/4, 2015 at 4:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.