i have array named content
content=[[{content:'gffdhdfhdfhdf'}],[{content:'gffdhdfhdfhdf'}],[{content:'gffdhdfhdfhdf'}],[{content:'gffdhdfhdfhdf'}]];
in botUI
botui.message.add({
content: 'Hello World from bot!'
}).then(function () { // wait till previous message has been shown.
botui.message.add({
delay: 1000,
human: true,
content: 'Hello World from human!'
});
});
i want to pass content from my array content in botui.message.add
with then means pass second object of content object in first then then third object inside of first then and so on and and when last then with last object have then but with different condition.
like:
botui.message.add({
content: content[0]
}).then(function () { // wait till previous message has been shown.
botui.message.add({
delay: 1000,
human: true,
content: content[1]
}).then(function () { // wait till previous message has been shown.
botui.message.add({
delay: 1000,
human: true,
content: content[n]
});
});
});
is this possible ?
yes you can, but create the array above
like so:
var content =['hello there','Nice to meet you']
Related
I'm trying to call the the founded variable outside of the array but it return an empty array instead. Can someone explain why the console.log inside the function work but not outside of the function.
// Video Schema
let mongoose = require("mongoose");
let Schema = mongoose.Schema;
var videoSchema = new Schema ({
title: String,
videoURL: String,
author: String,
time: String,
viewcount: Number,
categories: [{
type: Schema.Types.ObjectId,
ref: "Category"
}],
description: String,
})
let Video = mongoose.model("Video", videoSchema);
module.exports = {
videoSchema: videoSchema,
Video: Video
}
app.js
let Video = require(__dirname + "/dbs/Video.js").Video;
app.get("/", function(req,res) {
let videos = []
Video.find(function(err, foundVideo) {
if (!err) {
videos = foundVideo.slice(0)
console.log(videos) // this return me with an object array [{obj1}, {obj2}]
} else {
return err
}
})
console.log(videos) // This return an empty array []
}
How can I store the foundVideos array in the videos variable so that can call the variable global?
When you do this operation:
Video.find(function(err, data) {
// something
console.log("one")
})
// nothing
console.log("two")
The function between parentheses is the callback of the find() operation. This means it will be called back when the find execution ends, and it may make use of err or data parameters inside its scope. It will execute the console.log("one").
This way to "wait" for results is due to the asynchronous nature of js.
Instead, the code outside the callback method will be triggered just after the find is called, and it will not wait for the find operation to be finished. Therefore, in this example, two will be printed before one.
In your example, the variable videos you try to print outside the callback method console.log(videos) is empty as is printed before the videos are actually there.
You should write all your callback code in the !err case:
if (!err) {
videos = foundVideo.slice(0)
console.log(videos) // this return me with an object array [{obj1}, {obj2}]
}
Update
As you noticed, a coder is forced to implement the code in the callback method. Then, other methods or requests depending on the data from first request tend to make it complex to structure the code.
const processVideos = function(data) {
if(!data) {
// do something when data is empty
}
// process videos here
}
const notifyError = function(err) {
if(!err)
return
// do something with the error here
}
Video.find(function(err, data) {
processVideos(data)
notifyError(err)
})
Use always your "genius" and programming patterns to avoid complex code, large methods and unreadable sections.
I'm coding a very simple discord.js bot, and I have a command for when someone types /mahdi it returns a random response out of a list that I made. When it returned in a normal message, it would pick a random one each time, but then I made it so it sends in an embed, and now it picks one and sends that all the time, until I take the bot offline which then picks another one to send all the time when it goes back online.
Does anyone know what I'm doing wrong?
Code to randomly select a phrase from a list:
const mahdis = ['phrase1', 'phrase2', 'phrase3', 'phrase4', 'phrase5', 'phrase6', 'phrase7', 'phrase8'];
const mahdi = Math.floor(Math.random() * mahdis.length);
Code to send it as an embed:
const mahdiEmbed = {
color: 'c0ffee',
author: {
name: 'supreme sauce 3.0',
icon_url: 'https://cdn.discordapp.com/avatars/733259381898215495/739b2c90fbfab048abb236b0e89770be.webp?size=256',
},
fields: [
{
name: mahdis[mahdi],
value: '- mahdi',
},
],
footer: {
text: 'supreme sauce 3.0 --- developed by ed#6969',
icon_url: 'https://media.discordapp.net/attachments/693559044329177151/733614790567788574/kirbmelon.gif',
},
};
client.on('message', message => {
if(message.content === '/mahdi') {
message.channel.send({ embed: mahdiEmbed });
}
});
Thanks :)
Since you defined mahdi (which should be random every message) outside of your message event, it will be randomized only once, and that's when your bot starts.
If you put it in your message event, it will be randomized every new message. And that's what you want.
const mahdis = ['phrase1', 'phrase2', 'phrase3', 'phrase4', 'phrase5', 'phrase6', 'phrase7', 'phrase8'];
client.on("message", message => {
const mahdi = Math.floor(Math.random() * mahdis.length);
if (message.content.toLowerCase() == "mahdi") {
const mahdiEmbed = {
color: 'c0ffee',
author: {
name: 'supreme sauce 3.0',
icon_url: 'https://cdn.discordapp.com/avatars/733259381898215495/739b2c90fbfab048abb236b0e89770be.webp?size=256',
},
fields: [
{
name: mahdis[mahdi],
value: '- mahdi',
},
],
footer: {
text: 'supreme sauce 3.0 --- developed by ed#6969',
icon_url: 'https://media.discordapp.net/attachments/693559044329177151/733614790567788574/kirbmelon.gif',
},
};
message.channel.send({embed: mahdiEmbed});
}
})
I'm trying to triggering an edit on my embedded (already sent) message while keeping all the other fields the same value
I have found this answer as an inspiration (which works with the example): Embed message doesn't update but that doesn't seem to get all the fields, only the first. There isn't much more on the subject to find (or i'm not good at Googling :)).
So the new embed is just the first field and not all the (not changed) fields.
activityMsg = new Discord.RichEmbed({
title: 'Some text',
description: 'Description',
color: 3447003,
footer: {
icon_url: image,
text: image
},
thumbnail: {
url: image
},
fields: [
{
name: 'Text',
value: 'Text2',
},
{
name: 'Date and time',
value: '2pm',
},
{
name: 'Participants',
value: '#User',
},
{
name: 'Waiting list',
value: '#user2',
},
{
name: 'Max players',
value: '22',
}
]
});
const reactionFilterPlus = (reaction, user) => reaction.emoji.name === emoji_plus;
if(typeof title != undefined && title != null && data.length == 4 && error == ''){
var title = title[0].replace('[','').replace(']','');
// add reaction emoji to message
msg.channel.send(activityMsg)
.then(msg => msg.react(constants.emoji_plus))
.then(mReaction => {
// createReactionCollector - responds on each react, AND again at the end.
const collector = mReaction.message
.createReactionCollector(reactionFilterPlus, {
time: 15000
});
// set collector events
collector.on('collect', r => {
// immutably copy embed's Like field to new obj
let embedLikeField = Object.assign({}, activityMsg.fields[0]);
// update 'field' with new value
embedLikeField.value = `${user} <3`;
// create new embed with old title & description, new field
const newEmbed = new Discord.RichEmbed({
title: activityMsg.title,
description: activityMsg.description,
fields: [embedLikeField]
});
// edit message with new embed
// NOTE: can only edit messages you author
r.message.edit(newEmbed)
.catch(console.log);
});
})
.catch(console.log);
}
I expected this line to get all the fields, but that isn't the case.
// immutably copy embed's Like field to new obj
let embedLikeField = Object.assign({}, activityMsg.fields[0]);
I have tried let embedLikeField = Object.assign({}, activityMsg.fields[0] === 'Participants') but then I get the following error about a fieldname not present.
{ DiscordAPIError: Invalid Form Body
embed.fields[0].name: This field is required
at item.request.gen.end (/usr/src/app/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js:79:15)
at then (/usr/src/app/node_modules/snekfetch/src/index.js:215:21)
at process._tickCallback (internal/process/next_tick.js:68:7)
English isn't my native language and I'm stilling learning nodejs sorry sorry in advance about these points.
Object.assign() performes a shallow clone on the source, Are you trying to clone your entire embed or only its first field?
activityMsg.fields[0] refers to the first element in the list called fields within your activityMsg object. Try calling your assign() with activityMsg as source.
I am trying to get the children of apostrophe pages to appear in my navigation object - however the _children array is always empty. My page does have child pages set up via the front end Pages UI.
My index.js for the lib/modules/apostrophe-pages module contains the following:
construct: function(self,options) {
// store the superclass method and call at the end
var superPageBeforeSend = self.pageBeforeSend;
self.pageBeforeSend = function(req, callback) {
// Query all pages with top_menu setting = true and add to menu collection
self.apos.pages.find(req, { top_menu: true }, {slug: 1, type: 1, _id: 1, title: 1})
.children(true)
.toArray(
function (err, docs) {
if (err) {
return callback(err);
}
req.data.navpages = docs;
return superPageBeforeSend(req, callback);
});
};
},
...
My top_menu attribute is set via apostrophe-custom-pages:
module.exports = {
beforeConstruct: function(self, options) {
options.addFields = [
{
name: 'subtitle',
label: 'Subtitle',
type: 'string'
},
{
name: 'css_class',
label: 'CSS Class',
type: 'string'
},
{
name: 'top_menu',
label: 'Include In Top Menu',
type: 'boolean'
}
].concat(options.addFields || []);
}
};
This gives me the pages I need with the top_menu setting.. but I want to get child pages too..
When debugging the code I can see that the docs._children array is present but is always empty, even though a page has child pages...
I have tried adding the following both to my app.js and to my index.js but it doesn't change the result:
filters: {
// Grab our ancestor pages, with two levels of subpages
ancestors: {
children: {
depth: 2
}
},
// We usually want children of the current page, too
children: true
}
How can I get my find() query to actually include the child pages?
Solved it..
I needed to add 'rank: 1, path: 1, level: 1' to the projection as per this page in the documentation: https://apostrophecms.org/docs/tutorials/howtos/children-and-joins.html#projections-and-children
I am trying to get an array of documents where a child property is true. Here's some code:
public static getTeams(req, res) {
// Initialize a connection to the database
Globals.initDb(res).then((db: Db) => {
// Reference a collection in the Database
db.collection('teams', (error: Error, collection: Collection) => {
// Check if an error occured getting the collection
Globals.checkError({ error, result: collection, res }).then(() => {
// find teams that a user administrates
collection.find(
{ 'usergroups.users': { [req.params.id]: true } },
{ name: 1, icon: 1, type: 1, thumbnail: 1 }
).toArray((err, teams: Array<{ name: string, icon: string }>) => {
// make sure that went through OK
Globals.checkError({ error: err, result: teams, res }).then(() => {
if (!teams[0]) {
teams = [];
}
res.status(200).json(teams);
});
});
});
});
});
}
checkError is just a function I wrote to make it easier to check for errors, and it works fine, I checked it. I am trying to access an array of teams where the usergroups.users.#userId# is true. So if your id was j4k53, usergroups.users.j4k53 is true.
However, when it is true for multiple IDs, the documents are not returned. For example, if j4k53 and lfk3m are both true, it gets returned for neither of them.
Thank you for your help. (This is node with typescript, so it may look a little funky if you are not familiar with TS).
Got it: you can write it like this:
{ ['usergroups.users.' + req.params.id]: true}
Good luck to anyone who finds this useful!