2

I have my generator code like the following. I'm seeing some funny behavior when i run it. Once it ask the second Add property..., its also calling code under writing. Isn't supposed to run once prompting has completed? What am I doing wrong?

app/index.js

'use strict'
var generators = require('yeoman-generator');
var questions = require('./questions');

module.exports = generators.Base.extend({
   constructor: function () {
      generators.Base.apply(this, arguments);
      this.argument('name', { type: String, required: true });
   },

   initializing: function () {
      this.properties = [];
   },
   prompting: {
     askForProperties: questions.askForProperties
   },
   writing: function(){
     this.log("brewing your domain project");
   }
});

app/questions.js

'use strict'

var chalk = require('chalk');

function askForProperties() {
   var prompts = [
    {
        type: 'confirm',
        name: 'addProp',
        message: 'Add property to your model (just hit enter for YES)?',
        default: true
    },
    {
        type: 'input',
        name: 'propName',
        message: 'Give name to your property?',
        when: function (response) {
            return response.addProp;

        }
    },
    {
        type: 'list',
        name: 'propType',
        message: 'Pick a type for your property',
        choices: [
            {
                value: 'string',
                name: 'string',
            },
            {
                value: 'int',
                name: 'int'
            },
            {
                value: 'bool',
                name: 'bool'
            },
            {
                value: 'decimal',
                name: 'decimal'
            }],
        default: 0,
        when: function (response) {
            return response.addProp;

        }
    }
 ];

return this.prompt(prompts).then(function (answers) {
    var property = {
        propertyName: answers.propName,
        propertyType: answers.propType
    };

    this.properties.push(answers.propName);

    if (answers.addProp) {
        askForProperties.call(this);
    }
 }.bind(this));
}

module.exports = {
   askForProperties
};
rethabile
  • 3,029
  • 6
  • 34
  • 68

1 Answers1

0

It looks like you are battling the Yeoman object syntax. You are not returning the promise to the prompting method (you are returning an object with an askForProperties method that returns a promise)

For anyone looking into this it is in the Yeoman docs Running Context under the section titled Asynchronous Tasks

prompting() {
    const done = this.async();
    this.prompt(prompts).then((answers) => {
        this.log('My work after prompting');
        done();
    });
}

This allows the system to be aware of when your promise has returned and thus know to wait to execute the next priority steps.

However, what you really want to do is return a promise from the prompting() method itself.

prompting() {
    const promise = this.prompt(prompts).then((answers) => {
        this.log('Handling responses to prompts');
    });
    return promise;
}

In your specific case you've setup the promise correctly but you aren't returning it to the prompting property (just to the askForProperties property).

Since askForProperties is already returning the promise, your fix would be:

prompting: questions.askForProperties
purgatory101
  • 6,494
  • 1
  • 20
  • 21