javascriptnode.js

Passing in a result of a function to generate readme


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)
    }

Solution

  • 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
    }