Extracting values from multiple scope inside an array - javascript

I'm building a twitter bot that takes input of someone that DM's my account, and then will output the received DM's into tweet. I'm using twit package from npm. The question is, how do you extract the id's from the output, and then use the id's in another function in order to post the tweet, using? (note that I'm currently using console.log as the tweet for now).
Input command to check the direct messages
var listMsg = T.get('direct_messages/events/list', {
count: '50'
}, function(data, response) {
console.log(response)
Output in terminal (the multiple scope inside the events array)
{
events: [
{
type: 'message_create',
id: '1275746339314216965', //take this
created_timestamp: '1592996604170',
message_create: [Object]
},
{
type: 'message_create',
id: '1274664227584671750', //and this
created_timestamp: '1592738608629',
message_create: [Object]
}
]
}
Getting the content of a direct message
var getMsg = T.get('direct_messages/events/show', {
id:'1274664227584671750' //put it to this
}, function(data, response) {
//console.log(response)
let dm = response.event.message_create.message_data
console.log(dm) //and print the message here
The content of the direct message
{
text: 'Abcd',
entities: { hashtags: [], symbols: [], user_mentions: [], urls: [] }
}
I want to get the id's as a let just like in the third code block.

You can simply use the map array function to transform the object like this
events.map( function(e) { return e.id}) or you can use es6 syntax events.map(e=> e.id)
both would return an array like this
["1275746339314216965", "1274664227584671750"]
These could be joined into into a string like so
events.map(e=> e.id).join(",")
returning
"1275746339314216965,1274664227584671750"
map() is a great function try playing around with map reduce and filter to really improve your programming. There's a great article on them here https://medium.com/poka-techblog/simplify-your-javascript-use-map-reduce-and-filter-bd02c593cc2d
Of course you could do also use a good old fashioned for loop, but think that would be a bit verbose and unnecessary (the software equivalent of making your own hammer)
e.g.
var ids = []
for(var event of events) {
ids.push(event.id)
}

Related

How can I list all the records to see if they are duplicated?

I have a problem that I cannot resolve. I have a table in MongoDB, and this is structure:
const shopEconomy = new mongoose.Schema({
guildID: { type: String },
name: { type: String },
value: { type: Number },
description: { type: String },
rolereq: { type: String },
roleadd: { type: String },
roleremove: { type: String },
buyinfo: { type: String }
});
I need to list all names from the table (shopData.name) and then check if the typed name exists in the database. I tried to do something like the one below, but it doesn't work.
const shopData = await shopEconomy.find({ guildID: message.guild.id });
let categories = [];
let data = new Object();
for(const i in shopData){
data += `${shopData[i].name}\n`
categories.push(data)
}
Could someone take a look at this and help me out?
The title of the question does not quite match the description of the question. Given the description, let's assume the typed name is assigned to var typedName.
Let's also assume that you have bound your shopEconomy schema to a model that will actually interact with a mongodb collection called shopData. Then this will iterate all the docs in the shopData:
var found = false;
cursor = db.shopData.find(); // get EVERYTHING
cursor.forEach(function(doc) {
print(doc['name']);
if(doc['name'] == typedName) {
found = true;
}
});
if(found) {
print(typedName,"was found");
}
It is likely that the OP wants to find duplicate name in the collection, for which this pipeline will work:
db.shopData.aggregate([
{$group: {_id: '$name', N:{$sum:1}} },
{$match: {'N':{$gt:1}}}
]);
Part of the issue here comes from the use of a for...in loop which treats shopData as an object and loops over all properties of it. Instead try using a for...of loop which treats shopData as an array and loops over all objects in it.
...
for(const i of shopData) {
data += `${i.name}\n`
...
}
See also this question on for...in vs for...of and this question on JavaScript loops.

make the query dynamically to change using sanity.io groq

Hi there I'm trying to make a post request where I want to update one field on sanity.io
this is my query
patch: {
id: "f6c46b53-9313-4354-a4d6-7a40b06ee4c0",
set: {
`rewardItem[_key == \"${key}\"].lastTimeReward`: "TEst",
},
}
but this won't let me even run my project,
its giving me this error on console.log: Unexpected token;
When I do my query like this, it works
patch: {
id: "f6c46b53-9313-4354-a4d6-7a40b06ee4c0",
set: {
"rewardItem[_key == \"e88959e43ce7\"].lastTimeReward": "Test",
},
}
}]
Thanks a lot.
Your set-property is an object, and you can't enter a dynamic key directly into the object. To do what you are trying to do here, you can wrap the dynamic key in square brackets like this. That should give you the output you desire
const variable = "example"
const a = { [`template ${variable}`]: "value" }
console.log(a)

How to Access Nested Data in Object Maps / Collections

Say I have a collection that gets automatically returned in my app when I call a function, and it turns out something like this:
Collection {
'1234567890' => Message {
channel: TextChannel {
type: 'text',
id: '362557066864230402'
},
type: "DEFAULT",
content: "test"
}
}
I'm unsure about the '1234567890' => Message part. I understand that it's ES6, but I don't know how to call any of the nested data inside of it, such as content: "test".
To get to that (assuming the collection is using the variable collection, I've tried:
let data = collection["123567890"].content;
let data2 = collection[0].content; //I know that's for arrays, but I thought it would be similar
Both output 'null' or undefined, with the error
TypeError: Cannot read property 'content' of undefined
So I understand that I cannot get the initial collection object.
One last thing: That number 1234567890 is randomly generated each time the function is called, so I cannot hardcode anything easily.
Pastebin to the actual collection example.
For some reason, it stops printing after that line (possibly too many characters?)
EDIT: My code:
msg.channel.awaitMessages(msg => msg.author==user, { time: 10000, max: 1, errors: ['time'] })
.then((collected) => {
let channel = collected[0];
console.log(collected);
console.log(JSON.stringify(collected));
if(channel=="cancel") {
msg.channel.send("cancel");
return;
}
})
.catch(() => {
// ect ect
});
Sorry that there isn't much clarification, this is really stumping me.

Return all from type - Freebase MQL

Why does this return a 400 error (Unique query may have at most one result. Got 100):
[{
name:null,
type:'music/artist'
}]
I'd expect it to return the first 100 names from music/artist? How is it a unique query?
I'm trying to build a random query, where I can provide two params - the page and the result from within the page to return - and get one item back
Would be awesome if MQL supported something like return: 'random'
EDIT - adds full Angular factory. The query runs fine if I punch it in to the freebase.com/query engine.
myApp.factory('FB_Random', function ($http) {
return {
fn: function (callback) {
$http.get("https://www.googleapis.com/freebase/v1/mqlread",
{
params: {
query:[{
name: null,
type: '/music/artist'
}]
}
}
).success(function (d, status, headers, config) {
callback(d.result);
}).error(function (d, status, headers, config) {
console.log(d);
});
}
};
});
Looks like there's some undocumented Angular behavior going on here. According to the Angular docs, the params parameter takes a "Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url."
However, it seems like there's some additional logic that looks for array values in the params map and turns them into repeated parameters; ie. ?query={...}&query={...}. Since your query is (properly) wrapped in array notation, indicating that you're expecting multiple results, Angular interprets it as a list with a single value for the query parameter. It then extracts that query parameter and adds it to the url like so:
https://www.googleapis.com/freebase/v1/mqlread?query={%22name%22:null,%22type%22:%22/music/artist%22}
This is why you get the error about your query incorrectly asking for a single result. Because Angular removed the outer array notation that's needed by MQL.
The simplest way to work around this is to simply wrap your query in an additional array like this:
$http.get("https://www.googleapis.com/freebase/v1/mqlread",
{
params: {
query:[[{
name: null,
type: '/music/artist'
}]]
}
}
)
If you'd like to make the fix more explicit and your code easier to read you can just stringify the MQL query yourself like this:
$http.get("https://www.googleapis.com/freebase/v1/mqlread",
{
params: {
query: JSON.stringify([{
name: null,
type: '/music/artist'
}])
}
}
)

Using AngularJS $filter with ng-disabled

I've got an object in my $scope that contains a bunch of details about, say, an election. This object includes a voters array of objects, each with an _id:
$scope.election = {
voters: [
{ _id: '123' },
{ _id: '456' },
{ _id: '789' }
]
}
Also in my scope I have details about the currently logged in user:
$scope.user = { _id: '456' }
How can I bind ng-disabled to the presence of $scope.user._id in the array of objects $scope.voters?
What I've Tried
I have success simply displaying the presence of $scope.user._id in $scope.election.voters like this (Jade syntax):
pre(ng-bind="election.voters | filter:{user._id} | json")
When the current user is among the voters, they get displayed. When they're not among the voters, I get an empty array. That seems quite close to what I want.
But using the same filter (sans | json) with ng-disabled, I get the Angular Infinite $digest loop error.
Is this situation too complicated? Should I move it to a $filter? If so, how would I go about making it generic enough to be useful in a number of situations (if that's even feasible)?
Can run a simple filter right in controller, or using app.filter('filterName', func...) create a custom filter you can use in markup
$scope.userIsVoter = function() {
return $scope.election.voters.filter(function(el) {
return el._id == $scope.user._id;
}).length
}
<button ng-disabled="userIsVoter()">Do Something</button>

Categories

Resources