Repeat set of questions in InquirerJS - javascript

Is there a way to reset the questions or have a certain answer direct the question to another previous question?
var questions = [{
{
name: 'morefood',
message: 'Do you want more food?',
type: 'list',
choices: [ 'Yes', 'No'],
},{
name: 'choiceoffood',
message: 'Which food do you want more of?',
type: 'list',
choices: [ 'Hamburgers', 'Fries', 'Hotdogs']
when: function(answers) {
return answers.morefood === 'Yes';
}
}, {
name: 'quantityoffood',
message: 'How much more do you want?',
type: 'input',
when: function(answers) {
return answers.quantityoffood === 'Yes';
}
},{
name: 'confirmfood',
message: 'Do you still want more food?',
type: 'list',
choices: [ 'Yes', 'No'], <=========== if yes then goes back to choiceoffood
},
]

It seems a little hacky, but I believe you have to handle that in your application logic. For example:
const questionA = {
type: 'input',
message: 'Do you like fruit?',
name: 'questionA',
}
const questionB = {
type: 'input',
message: 'What is your favorite fruit?',
name: 'questionB',
}
const questionC = {
type: 'input',
message: 'what is your favorite candy?',
name: 'questionC',
}
inquirer
.prompt(questionA)
.then(answers => {
if (answers.questionA === 'yes') {
return inquirer.prompt(questionB)
} else {
return inquirer.prompt(questionC)
}
})
.then(answers => {
if (answers.questionB) {
return console.log(answers.questionB, 'is a great fruit');
}
if (answers.questionC) {
return console.log(answers.questionC, 'is a great candy');
}
})
UPDATE:
After looking at the docs a bit more, it seems 'when' is the correct solution for this.
when: (Function, Boolean) Receive the current user answers hash and
should return true or false depending on whether or not this question
should be asked. The value can also be a simple boolean.

Related

How can I break out of question loop on ENTER using inquirer.js?

I have the following task:
To terminate the procedure for adding users, it is enough to press ENTER instead of entering a name.
But when I use when in my code, the question is not displayed even the first time. Help me, please.
const questions = [
{
type: 'input',
name: 'user',
message: 'Pls, enter the user name or press ENTER to cancel:',
default: 'nnnnn',
validate: answer => {
if (answer === '') {
return 'Pls, enter a valid name';
}
return true;
},
// when(answers) {
// return answers.user === '';
// },
when(answers) {
answers.user === '';
},
},
{
type: 'list',
name: 'gender',
message: 'Pls, choose the gender:',
choices: ['male', 'female'],
default: 'male',
},

discord.js - TypeError [COMMAND_INTERACTION_OPTION_TYPE]: Option "user" is of type: STRING; expected USER

When I run the script for my discord bot and use /warn remove it keeps throwing an error that user is of type string expected USER. It says the error is happening between lines 69:42 and I can't find the issue.
module.exports = {
category: 'Moderation',
description: 'Warn a user',
permissions: ['ADMINISTRATOR'],
slash: true,
guildOnly: true,
options: [
{
type: 'SUB_COMMAND',
name: 'remove',
description: 'Removes a warning from the user',
options: [
{
name: 'user',
type: 'USER',
description: 'The user to remove the warning from',
required: true,
},
{
name: 'id',
type: 'STRING',
description: 'The ID of the warning to remove',
required: true,
},
],
}
],
callback: async ({ guild, member: staff, interaction }) => {
const user = interaction.options.getUser('user')
if (subCommand === 'remove') {
const warning = await warnSchema.findByIdAndDelete(id)
return {
custom: true,
content: `Removed warning ${warning.id} from <#${user?.id}>`,
allowedMentions: {
users: []
}
}
}
}
}
I didn't post all the code because it seemed like it would be too much searching but this is the code that is causing the error.

How to display unique items and the amount of occurances from an array of objects in Vuejs/JS?

I'm working on an inventory app with Vuejs for this project, but my problem is specifically a JS related one.
In my data I have the user data which is the logged userData which is taken from a form and then the static categories and locations which you can choose from below that.
I am trying to pull out the unique categories and how many times the appear in a new array of objects that would look like :
[{title: 'Books', amount: 3 }, {title: 'Recods', amount: 1 }, ...]
I believe what I have is a scope issue.
Data
userData: {
items: [
{
itemName: 'test book',
category: 'Books',
location: 'Kitchen',
},
{
itemName: 'test book 2',
category: 'Books',
location: 'Garage',
},
{
itemName: 'test book 3',
category: 'Books',
location: 'Basement',
},
{
itemName: 'test record',
category: 'Records',
location: 'Basement',
},
{
itemName: 'test furniture',
category: 'Furniture',
location: 'Garage',
},
],
categories: ['Books', 'Movies', 'Records', 'Furniture'],
locations: ['Basement', 'Garage', 'Kitchen'],
},
I'm trying to get this to work like I have here with 'Books', but for all categories.
This is what I have displaying with the code below. It reads 'Items: 3' because I have 3 Books in my userData, but I need it to display the amount for each unique category.
I cannot figure out what to place in the code below
filteredItems = items.filter((item) => item.category === 'Books').length
method/function
convertedCategories() {
const items = this.userData.items
const filteredItems = items.filter((item) => item.category === 'Books').length
function getItemCountOfCategory(categoryName) {
return filteredItems
}
function convertCategoriesIntoCards(categories) {
return categories.map((el) => {
return {
title: el,
amount: getItemCountOfCategory(el),
}
})
}
return convertCategoriesIntoCards(this.userData.categories)
},
I apologize if I haven't broken this down clear enough; it's still very hard for me to extract a particular line that pertains to the question out of so much code.
If anything is unclear, please let me know!
Something like this should work.
convertedCategories() {
const items = this.userData.items
function getItemCountOfCategory(categoryName) {
return items.filter((item) => item.category === categoryName).length
}
function convertCategoriesIntoCards(categories) {
return categories.map((el) => {
return {
title: el,
amount: getItemCountOfCategory(el),
}
})
}
return convertCategoriesIntoCards(this.userData.categories)
},

Different conditions, same result. Why?

Creating a sort function for a very simple todo app in a Javascript tutorial. My answer and the tutorials answer are different but yield the same results. I know different code can achieve the same results but I'm just wondering why? I'm not sure how to test my code to see where it could fail. Code below.
CODE:
const todoList = [{
title: 'Work on JS course',
completed: true
}, {
title: 'School activity with Eleanor',
completed: false
}, {
title: 'Coach Susan',
completed: true
}, {
title: 'Go over Step study homework',
completed: false
}, {
title: 'Message car buyer',
completed: true
}]
//my answer
const sortTodo = function (todoList) {
todoList.sort(function (a, b) {
if (a.completed < b.completed) {
return -1
} else if (b.completed < a.completed) {
return 1
} else {
return 0
}
})
}
//video answer
const sortTodo = function (todoList) {
todoList.sort( function (a, b) {
if (!a.completed && b.completed) {
return -1
} else if (!b.completed && a.completed) {
return 1
} else {
return 0
}
})
}
answer: (my answer and the video answer both get this result)
$ node todo.js
[ { title: 'School activity with Eleanor', completed: false },
{ title: 'Go over Step study homework', completed: false },
{ title: 'Work on JS course', completed: true },
{ title: 'Coach Susan', completed: true },
{ title: 'Message car buyer', completed: true } ]

inquirer package, present questions based on previous answers

I'm using NPM 'inquirer' package in order to present the user various questions. One of them is a 'choices' selection.
Is there a way to present follow up questions based on the 'choices' selection?
Here's my code:
const { prompt } = require('inquirer');
require('colors');
const questions = [
{
type: 'input',
name: 'appName',
message: 'Enter application name:'
},
{
type: 'input',
name: 'appDescription',
message: 'Enter app description:'
},
{
type: 'input',
name: 'appAuthor',
message: 'Enter app author:'
},
{
type: 'checkbox',
name: 'plugins',
message: 'Select plugins to install:',
choices: [
{
name: 'Cassandra'
}
]
}
];
module.exports.performQuestions = async () => {
console.log('\nWelcome to Chef!\n'.underline.italic.cyan);
const answers = await prompt(questions);
if (!answers.appName) {
console.error('\nPlease provide app name!\n'.red);
process.exit(1);
}
answers.appType = 'service';
return answers;
};
Here I want to present a few more questions if the user selects 'Cassandra' is that possible?
Thanks.
You can use "when" and like in the example bellow, the second question will popup only if "Cassandra" is selected:
const QUESTIONS = [
{
name: 'your-name',
type: 'list',
message: 'Your name:',
choices: ['Batman', 'Superman', 'Ultron', 'Cassandra'],
},
{
name: 'hello-cassandra',
type: 'confirm',
message: 'Oh, hello Cassandra!',
when: (answers) => answers['your-name'] === 'Cassandra',
},
];
inquirer.prompt(QUESTIONS)
.then(answers =>
{
console.log(answers);
});

Categories