Modify Choice Validation in Choice Prompt - Bot Framework Node.js - javascript

Currently having a choice_prompt that asks the user for some options to validate. To move to the next step of the waterfall, the user's input has to either be the value, or a synonym associated with that value.
If a user types something that is not the value or synonym, the choicePrompt just loops. I want to warn the user "Enter a number between 1 - 6".
async question2_1(step) {
return await step.prompt(CHOICE_PROMPT, {
prompt: '"1/3: How easy were the course materials to navigate and follow?',
choices: ChoiceFactory.toChoices([' = Very Hard', '', '', '', '', ' = Very Easy']),
style: ListStyle.list
});
}

You need to add a retryPrompt option like this:
async question2_1(step) {
return await step.prompt(CHOICE_PROMPT, {
prompt: '"1/3: How easy were the course materials to navigate and follow?',
choices: ChoiceFactory.toChoices([' = Very Hard', '', '', '', '', ' = Very Easy']),
style: ListStyle.list,
retryPrompt: 'Enter a number between 1 - 6'
});
}
If you want any of the original prompt to be re-prompted, you'll need to add that too. The user will only get re-prompted with the text you add under retryPrompt.
EDIT: I was looking at this again to use synonyms and I think despite displaying as a numbered list, you aren't going to get the expected values with all those null strings. Maybe I'm wrong because I haven't done a choice like that, but I would probably explicitly define my choices like below. This allows you to set a separate Title (shown) and Value (send on backend) for each choice, as well as add synonyms if you want (you can also add synonyms with the simpler definition as you have above).
async question2_1(step) {
return await step.prompt(CHOICE_PROMPT, {
prompt: '"1/3: How easy were the course materials to navigate and follow?',
choices: [
{value:'1', action: {type: 'imBack', title: '= Very Hard', value: '1'}, synonyms: ['1']},
{value: '2', action: {type: 'imBack', title: ' ', value: '2'}, synonyms: ['2']},
{value: '3', action: {type: 'imBack', title: ' ', value: '3'}, synonyms: ['3']},
{value: '4', action: {type: 'imBack', title: ' ', value: '4'}, synonyms: ['4']},
{value: '5', action: {type: 'imBack', title: ' ', value: '5'}, synonyms: ['5']},
{value: '6', action: {type: 'imBack', title: '= Very Easy', value: '6'}, synonyms: ['6']},
],
style: ListStyle.list,
retryPrompt: 'Enter a number between 1 - 6'
});
}

Related

React Select - Default Value from Redux not working

I've data coming from Redux in this format:
[
0: {value: '1.5', label: 'Extra cheese'}
1: {value: '3', label: 'Tomato'}
]
and i try to load them into my react-select.
But it fails, bcs it loads instantly the initialToppings as defaultValue (So it shows me empty Strings as defaultValue). And this Value can never be changed again. But without initialToppings i get nothing at defaultValue bcs redux is to slow and the defaultValue is empty so i can't load it in again later...
const initialToppings = [{ label: '', value: '' }];
const [defaultToppings, setDefaultToppings] = useState(initialToppings);
useEffect(() => {
setDefaultToppings(
editProduct?.selectedToppings?.map((topping, value) => ({
...topping,
value,
})) ?? initialToppings
);
}, [editProduct]);
<Select
options={extraOptions}
formatOptionLabel={formatExtras}
isMulti
defaultValue={defaultToppings}
// defaultValue={[
// { label: 'Test 1', value: '1' },
// { label: 'Test 2', value: '2' },
// ]}
onChange={setSelectedToppings}
/>
You can add key props to Select to force remounting component and make it re-render
<Select
key={defaultToppings}
options={extraOptions}
formatOptionLabel={formatExtras}
isMulti
defaultValue={defaultToppings}
// defaultValue={[
// { label: 'Test 1', value: '1' },
// { label: 'Test 2', value: '2' },
// ]}
onChange={setSelectedToppings}
/>
I've a simple codesandbox, you can check it

How can send data from an array in one embed message (discord.js)

I want to send data from an array in one embed message with few fields but my code sends them as 4 different embed messages with one field
I tried with this Code :
const pListEmbed = new Discord.MessageEmbed()
.setColor('#03fc41')
.setTitle('Connected')
.setDescription(Total : ${list.length})
.setThumbnail(config.logo)
.addFields(
array.flatMap(user => [
{ name: 'ID', value: user.id, inline: true },
{ name: 'Name', value: user.user_name, inline: true },
{ name: 'Identifier', value: user.identifier, inline: true }
])
)
)
.setTimestamp(new Date())
.setFooter('Used by: ' + message.author.tag, ${config.SERVER_LOGO});
message.channel.send(pListEmbed);
But it sends 4 embed messages with just one field that have id,username and identifier, and i don't want it like this. I want it to send one embed message with 4 different fields that have these 4 id,username and identifiers (we don't know how many of them we have)
Array :
[
{
id: '46892319372',
user_name: 'testerOne',
identifier: '20202'
}
]
[
{
id: '15243879678',
user_name: 'testerTwo',
identifier: '20201'
}
]
[
{
id: '02857428679',
user_name: 'testerThree',
identifier: '20203'
}
]
[
{
id: '65284759703',
user_name: 'testerFour',
identifier: '20204'
}
]
Your question is very unclear. If you want to send one embed for every user containing the ID, name and identifier, then you could do this:
list.forEach(user => {
const pListEmbed = new Discord.MessageEmbed()
.setColor('#03fc41')
.setTitle('Connected')
.setDescription(Total : ${list.length})
.setThumbnail(config.logo)
.setTimestamp(new Date())
.setFooter('Used by: ' + message.author.tag, ${config.SERVER_LOGO});
.addFields(
{
name: "ID"
value: user.id,
inline: true
},
{
name: "Name"
value: user.user_name,
inline: true
},
{
name: "Identifier"
value: user.identifier,
inline: true
}
)
message.channel.send(pListEmbed);
})
If on the other hand you want to send one embed only and it contains all the IDs, all the names, and all the identifiers, then this is impossible. Embed have character limits and since you don't know how many users you have, there could be thousands, thus busting the limit. And that would block you from sending the embed.
Also your "array" is in fact multiple arrays containing only one element each. I don't know if that's what you intended or not but it's not an array but multiple little ones.

Embed Formatting Inline

The current embed I have looks like this:
However, I want the sections named Total to be in the same line. I'm not sure how you break the inline without the second Total not being in the same line as well.
The result I'm looking for:
My current code:
//ignore the card[1], card[0], etc. Those are arrays for what I want to post as emoji's/card values
const embed = new Discord.MessageEmbed()
.setTitle(`Blackjack`)
//card[1] = rank; card[0] = suit
.addFields(
{ name: 'Your Hand', value: `${card[1]}${card[0]}${card3[1]}${card3[0]}`, inline: true },
{ name: "Dealer's Hand", value : `${card2[1]}${card2[0]}`, inline: true },
{ name: "Total: [calculate later]", value: "\u200B" },
{ name: "Total: [to create later]", value: "\u200B", inline: true },
)
.setFooter("Commands\n!stand\n!hit\n!double\n!fold\n!split");
message.channel.send(embed);
I think it would be easier to add the total value in the same column by including it in the hands' value on the next line after the cards. You could also add some extra space between the two columns:
const embed = new MessageEmbed().setTitle(`Blackjack`).addFields(
{
name: 'Your Hand',
value: `A♦2♠7♦\n\nTotal: **10/20**`,
inline: true,
},
{
name: '\b',
value: '\b',
inline: true,
},
{
name: "Dealer's Hand",
value: `K♦4♣\n\nTotal: **14**`,
inline: true,
},
);
message.channel.send(embed);
You need to set both field's inline option to true. Keep in mind that the result may be different on different sized screens
{ name: "Total: [calculate later]", value: "\u200B", inline: true},
{ name: "Total: [to create later]", value: "\u200B", inline: true},

Combine two expect statements that perform check on single json response

I'm writing a test to check that a function in my Node.js application which returns this JSON structure:
}
id: 1,
name: 'John Doe',
email: 'j#doe.com',
phone: '+123',
suppliers: [
{
id: 1,
name: 'Supplier1'
}
]
}
I have this expect:
expect(res.body.users[0]).to.be.an.instanceof(Object)
.that.includes.all.keys([
'id',
'name',
'suppliers',
]);
I also want to check there are details in suppliers. I could just add this in another expect:
expect(res.body.users[0].suppliers[0]).to.be.an.instanceof(Object)
.that.includes.all.keys([
'id',
'name',
]);
Is it possible to combine both into one expect statement though?

Adding two lists to selectize, the first one should be selected by default

Hi I've a litle problem with selectize, namely how to add two lists and he first one should be selected by default and enduser can select items from second list in same form. Below you can find my code. If I add two times options selectize takes second one only).
$(document).ready(function(){
lol = "lol1 , lol2 , lol3"
var lol = lol.split(',');
var lol = lol.map(function(x) { return { item: x}; });
console.log(lol)
console.log(typeof(lol))
wtf = "wtf1 , wtf2 , wtf3"
var wtf = wtf.split(',');
var wtf = wtf.map(function(x) { return { item: x}; });
console.log(wtf)
console.log(typeof(wtf))
$('#show_tags').selectize({
plugins: ['remove_button', 'restore_on_backspace'],
select: true,
delimiter: ',',
maxItems: null,
options: lol,
options: wtf,
labelField: 'item',
valueField: 'item',
searchField: 'item',
create: true
});
});
Ideas?
You need to use items to provide an array of values for the options that should be selected by default (instead of using two options arrays). Option values are determined by your valueField setting.
For example:
$('#select-id').selectize({
items: ['1', '2'], // preselected options values
options: [
{ value: '1', name: 'Item 1' }, // this option will be preselected
{ value: '2', name: 'Item 2' }, // this option will be preselected
{ value: '3', name: 'Item 3' },
{ value: '4', name: 'Item 4' }
],
valueField: 'value',
labelField: 'name',
searchField: ['name'],
delimiter: ',',
select: true,
create: true,
maxItems: null
});

Categories