It is possible to create branching questions with inquirer? - javascript

const employeeQuestion = [
{
type: "list",
name: "employeeTitle",
message: "What's the employee's title",
choices: ["Engineer", "Intern"]
},
//when role is engineer is true, ask this question
{
when: input => {
return input.role == "Engineer"
},
type: "input",
name: "github",
message: "Enter your github username:",
},
//when role is intern is true, ask this question
{
when: input => {
return input.role == "Intern"
},
type: "input",
name: "school",
message: "What's the school you enrolled in ?",
},
]
The idea is I want to utilize inquirer's when method so the question whether to ask about the user's github or school is dependent on the answer on the employee's title. But when i run node on the command line, the question asking for github / school never appeared. I wonder if I used the method wrong or if there are other alternatives.

inquirer's when method is definitely the correct one for this situation!
There are two possible reasons:
You are using input.role but never defining a role value in the answers hash. You need to refer to the name value from the earlier question, in this case, input.employeeTitle.
If reason 1 does not fix it, try expanding your function a bit. when needs to take in the answers hash as an input, then apply the conditional to that and explicitly return a Boolean. Ex.
{
type: "input",
name: "github",
message: "Enter your github username:",
when: (answers) => {
if (answers.employeeTitle === "Engineer") {
return true;
}
}

Related

Make custom this.$myfunction in vueJS (V2)?

I'm making an admin dashboard and I need to ask for data (for example when creating or updating data) a lot. I am already using vue-sweetalert2 which made me aware of how easy it is to use this.$swal.fire().then()...
I was wondering, how would I go about making my own kind of thing like that (without using TypeScript)?
let reply = await this.$ask(fields)
alert("You entered: " + reply.yourname.answer)
Then in the component that I load in on every page, I would have a modal which takes the fields and allows for user input. When a user clicked submit or exited the modal, it needs to return a / the value(s).
I'm thinking of using it this way:
// Ask for new team name & description
let modalResult = await this.$ask({
fields: [
{
title: "Team name",
placeholder: "Give youre team a name!",
key: "teamName",
type: "text"
}, {
title: "Team description",
placeholder: "What's your team about?",
key: "teamDescription",
type: "text"
}
],
modal: {
variant: "primary",
icon: null,
title: "Make a new team",
confirmButtonText: "Create team",
cancelButtonText: "Cancel"
}
});
console.log("Team name: " + modalResult.data.teamName);
console.log("Team description: " + modalResult.data.teamDescription);
However, I honestly have no idea how I'd go about making this possible. What I've thought of:
Mixins: Of what I've learnt so far, I don't know how to put a template file in it. (so a .vue file, only a .js file).
Here's a screenshot of :
what I'm trying to say
Thanks in advance! :-)
When you're setting up your vue instance (usually in main.js), you can put your method on as a prototype
Vue.prototype.$ask= (your function or your object);
Here's some vuejs docs on the subject
https://v2.vuejs.org/v2/cookbook/adding-instance-properties.html

Keep repeating the prompter questions with Inquirer.js based on answer?

I'm using Inquirer.js to create a CLI's prompter which allows users to enter/reply to some input/questions. In the last question, I want to add a feature that if the user replies no to Are you done? question, then the prompter will restart asking the questions until the user replies yes. I'm almost there with the functionality.
It's working, but only on the first time when I enter no. The second time I enter no, the prompter stops.
How can I run this on a loop to accomplish the desired behavior? What I'm doing wrong?
This is what I have some far:
import inquirer from 'inquirer';
inquirer
.prompt([
// { bunch of other questions previously },
{
type: 'confirm',
name: 'repeat_questions',
message: 'Are you done?',
},
])
.then((answers) => {
if (answers.repeat_questions) {
return inquirer.prompt([
// { bunch of other questions previously },
{
type: 'confirm',
name: 'repeat_questions',
message: 'Are you done?',
},
]);
}
})
.catch((error) => {
if (error.isTtyError) {
throw new Error(`Prompt couldn't be render in current environment`);
}
});
One way is a recursive function:
import inquirer from "inquirer";
const questions = [
{
type: "number",
name: "children_count",
message: "How many children do you have?",
},
{
type: "input",
name: "first_child_name",
message: "What is the eldest child's name?",
},
{
type: "confirm",
name: "is_finished",
message: "Are you done?",
},
];
function getAnswers() {
return inquirer.prompt(questions).then((answers) => {
if (answers.is_finished) {
return answers;
} else {
return getAnswers();
}
});
}
getAnswers()
.then(console.log)
.catch((error) => {});
The variable repeat_questions doesn't make sense, if the user says no to if they are done, repeat_questions is also no. So instead I renamed it to is_finished.

MS Teams adaptive card "herocard" not work on mobile

I`m creating bot for MS Teams and using JS Microsoft Bot Framework V4 SDK.
In my work, I use search message extension and to work with it, I implemented the onSelectItem method that returns a adaptive card. I will give an example of the code below.
return Promise.resolve({
type: "result",
attachmentLayout: "list",
attachments: [CardFactory.heroCard(
`${file.name}`,
`${text}`,
undefined,
CardFactory.actions([
{
type: "openUrl",
title: "Open",
value: `${openLink}`
},
{
type: "openUrl",
title: "Download",
value: `${downloadLink}`
},
]),
)]
});
Where I pass undefined, this should be the path to the picture, but in my implementation I don't need it. So and this code works great in the browser and on the desktop version here is a screenshot
however, on the mobile version, I get the following result
this is absolutely not the right card, it has no content or buttons
I think I found the answer myself. When the message extension search is triggered, the onQuery method is called and suppose you made a query and received an array of values ​​that you want to display. And here, in the same method, iterating over the array, you must draw two cards at once. For example
files.forEach((file: IDocumentInfo): void => {
const card: any = CardFactory.heroCard(
cutString(file.name, LIMIT),
text,
undefined,
[
{
type: "openUrl",
title: "Open",
value: "", // some value
},
{
type: "openUrl",
title: "Download",
value: "" //some value,
},
]
);
const preview: any = {
contentType: "application/vnd.microsoft.card.thumbnail",
content: {
title: `${cutString(file.name, LIMIT)}`,
text: "", // some text
}
};
And here the variable preview in my case will respond to a small view of information after the search and the variable card will be responsible for the view after selection. And after the card is selected, the onSelectItem method is triggered, which I need to get more information about the document
It turns out that the adaptive heroCard is not to blame here, the onSelectItem method is not called in the mobile application, or I am doing something wrong

JS library to check if extra data field returned in http response payload?

I’m currently working on building end-to-end testing for an API another team is working on, and I was wondering if anyone perhaps knows about a JS library that I could use to test whether an extra field is returned in HTTP response body? The purpose of this functionality would be to keep the QA team informed when the dev team makes changes to the api via the tests, instead of the developers manually having to let us know they’ve created updates. I know this can be implemented manually but if the wheel already exists, I’d prefer to avoid recreating it lol.
Example scenario:
API call: GET user
- returns : user name, user ID and user birthday.
With proposed functionality, if the dev team made updates to the Get user call, and it returns the following
- return : user name, user ID, user birthday AND user address.
A test would fail to let me know that an extra field that wasn't expected (user address) was returned.
Schema validation seems to be what you are looking for. Besides the library mentioned in another answer, you may also want check a similar one: joi
const Joi = require('joi');
const schema = Joi.object().keys({
userName: Joi.string().alphanum().required(),
userId: Joi.number().required(),
userBirthDay: Joi.number().required(),
})
const result = Joi.validate({
userName: 'johndoe',
userId: 1234567,
userBirthDay: 1970,
userAddress: 'John Doe St.'
}, schema);
if (result.error) {
console.log(result.error.details);
}
In the spec you can make assertion on existence of error key in result object using the assertion library of your choice.
The example above assumes that you are using nodejs as an environment to run tests, but browser version of joi also exists: joi-browser
You need schema validation, there are libraries out there like ajv.
var ajv = new Ajv({ allErrors: true }); // options can be passed, e.g. {allErrors: true}
// API call: GET user - returns : user name, user ID and user birthday.
// With proposed functionality, if the dev team made updates to the Get user call, and it returns the following - return : user name, user ID, user birthday AND user address.
var schema = {
type: "object",
properties: {
userName: {
type: "string",
},
userId: {
type: "string",
},
userBirthdate: {
type: "string",
},
},
required: ["userName", "userId", "userBirthdate"],
additionalProperties: false,
};
var validate = ajv.compile(schema);
var validUser = {
userName: "John",
userId: "john",
userBirthdate: "01012000",
};
var invalidUser = {
userName: "John",
userId: "john",
userBirthdate: "01012000",
userAddress: "World",
};
var valid = validate(validUser);
console.log(`Valid user is valid: ${valid}`);
valid = validate(invalidUser);
console.log(`Invalid user is valid: ${valid}`);
console.log('Validate errors:', validate.errors);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.6.2/ajv.min.js"></script>

Ajv keywords and custom error messages

I have written a schema but it does not seem to be validating as I was expecting. I'm assuming there is something wrong with my schema syntax but cannot figure it out. I expect not to see error messages for title or target until fundraiser is complete since they are only required if fundraiser is completed. I've tried many combinations but none of them are working as expected, these two are the closest I've come to what I need.
Schema attempt one: shows 4 error messages, 3 required errors and 1 error saying data should match "then" schema.
const schema = {
required: ['fundraiser'],
if: {
properties: {
fundraiser: { type: 'string' },
},
},
then: {
required: ['title', 'target'],
},
errorMessage: {
required: {
fundraiser: 'Please select an option',
title: 'Please enter a title',
target: 'Please enter a target',
},
},
};
Schema attempt two: shows 2 error messages, 1 required error and 1 error saying data should match "then" schema which is correct but then when I complete fundraiser valid becomes true which is when I expect to then see required errors for title and target. Also no errors have my defined custom error messages.
const scema = {
if: {
properties: { fundraiser: { minLength: 2 } },
then: { required: ['title', 'target'] },
},
then: { required: ['fundraiser'] },
errorMessage: {
required: {
fundraiser: 'Please select an option',
title: 'Please enter a title',
target: 'Please enter a target',
},
},
};
I am pretty sure that I am doing something wrong with my schema but it is not clear from the documentation how to use if/then in combination with custom error messages using ajv-errors. Any help would be greatly appreciated! Thanks!
The problem with the first schema is that subschema inside “if” is valid, unless fundraiser property is present and not a string. It would probably work as you expect if you add type: 'object' to the root schema and move required inside “if” subschema.
The problem with the second subschema is that the first “then” that has no “if” in the same schema object is ignored (unless you are using ajv-keywords that implemented if/then/else somewhat differently from how it is defined in draft-07 of JSON Schema spec) and the subschema inside “if is valid even if fundraiser property is absent and the second “then” can only pass if fundraiser is present.

Categories