Home > OS >  Passing in a result of a function to generate readme
Passing in a result of a function to generate readme

Time:12-09

Bootcamp student here. I seem to be having trouble passing in the result of function renderBadge(license) to the generateREADME function. I am using inquirer to grab inputs, and generate a readme. The functions renderBadge() and licenseLink() is solely pertaining to license portion of the inquirer. However, I can't seem to pass this info along and display it to the generating function. Is there a way to do this? What am I doing wrong? Thanks in advance.

Upon function execution, the ${badge} seems to be undefined. Result of execution

const inquirer = require("inquirer");
const fs = require("fs");

const generateREADME = ({ title, description, installation, usage, contributions, tests, license, github, email, badge,}) =>

    `# ${title} 
    ${badge}
    
    ## Description

    ${description}

    (Rest of Readme Generation here)
    `

inquirer
    .prompt([
        { 
            (other prompts here)
        },
        {
            type: "list",
            name: "license",
            message: "What license is your project?",
            choices: [
            "Apache 2.0",
            "Boost",
            "GNU AGPL v3",
            "MIT",
            "Perl",
            "other",
            ],
            validate: (licenseInput) => {
            if (licenseInput) {
                return true;
            } else {
                console.log(`Please enter your project's license!`);
                return false;
            }
            },
        }
    ])
    .then((answers) => {
      const readmePageContent = generateREADME(answers);
      renderBadge(answers)

        fs.writeFile('README.md', readmePageContent, (err) => {
            err ? console.log(err) : console.log('Successfully generated README!')
        })
    })

    function renderBadge(license) {
        let badge = ''
        if (license === 'Apache 2.0') {
            badge = `![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)]`
        } else if (license === 'Boost') {
            badge = `![License](https://img.shields.io/badge/License-Boost_1.0-lightblue.svg)]`
        } else if (license === 'GNU APGL v3') {
            badge = `![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)]`
        } else if (license === 'MIT') {
            badge = `![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)]`
        } else if (license === 'Perl') {
            badge = `![License: Artistic-2.0](https://img.shields.io/badge/License-Perl-0298c3.svg)]`
        } else {
            badge = ''
        }
        return badge;
        generateREADME(badge)
    }

CodePudding user response:

The main issue here is the way you pass/accept arguments.

answers is an object containing the key/value-pairs an example could be:

const answers = {
  title: "Hello World",
  description: "Hello World, this is a test description",
  // ...
  license: "GNU AGPL v3",
};

You then pass the answers object to renderBadge.

renderBadge(answers)

However in renderBadge you expect license as the sole argument.

function renderBadge(license) {
  // ...
}

Since you passed the whole answers object, that is what you will receive. Meaning that the licence parameter will contain the answers object.

To fix this you should pass just the license to renderBadge, not all the answers. So use renderBadge(answers.license) instead.

Alternatively you could also use object destructuring like you did in generateREADME, and define renderBadge as:

function renderBadge({ license }) {
  // ...
}

If you choose to use object destructuring, you should still pass the full answers object to renderBadge, so renderBadge(answers).


The second, non-essential mistake is:

return badge;
generateREADME(badge) // never executed

The line after the return is never executed. This doesn't really break anything, since you didn't need that line anyways, so it can just be removed.


Lastly, and probably most importantly the order of the following lines are incorrect.

const readmePageContent = generateREADME(answers);
renderBadge(answers.license) // after the first fix

The renderBadge() call should be made before you render the readme file, the resulting contents should then be passed as argument to generateREADME().

const badge = renderBadge(answers.license);
const readmePageContent = generateREADME({ ...answers, badge });

This uses the spread syntax in object literals combined with the property definition shorthand to pass a single object, containing al the required arguments.


So the final result might look like this (with minimum changes):

const inquirer = require("inquirer");
const fs = require("fs");

const generateREADME = ({title, description, installation, usage, contributions, tests, license, github, email, badge,}) => (
    `# ${title} 
    ${badge}
    
    ## Description

    ${description}

    (Rest of Readme Generation here)
    `
);

inquirer.prompt([
    { 
        (other prompts here)
    },
    {
        type: "list",
        name: "license",
        message: "What license is your project?",
        choices: [
            "Apache 2.0",
            "Boost",
            "GNU AGPL v3",
            "MIT",
            "Perl",
            "other",
        ],
        validate: (licenseInput) => {
            if (licenseInput) {
                return true;
            } else {
                console.log(`Please enter your project's license!`);
                return false;
            }
        },
    }
]).then((answers) => {
    const badge = renderBadge(answers.license); // pass only the license, not all the anwers
    const readmePageContent = generateREADME({ ...answers, badge }); // pass the answers combined with the badge

    fs.writeFile('README.md', readmePageContent, (err) => {
        err ? console.log(err) : console.log('Successfully generated README!')
    })
});

function renderBadge(license) {
    let badge = ''
    if (license === 'Apache 2.0') {
        badge = `![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)]`
    } else if (license === 'Boost') {
        badge = `![License](https://img.shields.io/badge/License-Boost_1.0-lightblue.svg)]`
    } else if (license === 'GNU APGL v3') {
        badge = `![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)]`
    } else if (license === 'MIT') {
        badge = `![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)]`
    } else if (license === 'Perl') {
        badge = `![License: Artistic-2.0](https://img.shields.io/badge/License-Perl-0298c3.svg)]`
    } else {
        badge = ''
    }
    return badge; // removal of generateREADME
}

CodePudding user response:

When you put a return statement in a function, all the code below it doesn't execute.

In your renderBadge function, you invoke generateREADME(badge) after the return statement. So it never runs:

  function renderBadge(license) {
        let badge = ''
        ...
        } else {
            badge = ''
        }
        return badge;
        generateREADME(badge)  // this line doesn't execute
    }

To call generateREADME() with the renderBadge function output, you need to remove the generateREADME(badge) statement:

function renderBadge(license) {
        let badge = ''
        ...
        } else {
            badge = ''
        }
        return badge;
    }

After that, call the function in the relevant place and store the output in the variable like so:

...
 .then((answers) => {
      const readmePageContent = generateREADME(answers);
      input = renderBadge(answers)
      generateREADME(input)
       

Or you can do it succinctly like this:

...
 generateREADME(renderBadge(answers))
...
  • Related