Discord JS getting text and value of a field - discord.js

I have been trying to make it so whenever an embed is sent, I gather it and then I try to send it in another channel.
I can't get the value and name which are inside the field.
My code:
client.on('message', message => {
if (message.channel.id == channel1)
{
console.log(message.embeds);
console.log("------------------------");
console.log("------------------------");
console.log("------------------------");
console.log("------------------------");
console.log(message.embeds[0].title);
console.log(message.embeds[0].description);
console.log(message.embeds[0].color);
console.log(message.embeds[0].fields);
console.log(message.embeds[0].image.url);
console.log(message.embeds[0].footer.text);
}
});
How I tried to retrieve the name and value inside of the field:
message.embeds[0].fields.name
message.embeds[0].fields.value
But these return undefined, so I don't know how to retrieve the value.

MessageEmbed.fields is an array. You need to get the first element from that to read the name and value
console.log(message.embeds[0].fields[0].name);
console.log(message.embeds[0].fields[0].value);
Keep in mind fields[0] may be undefined if there are no fields

Related

Form Submit Iterating for Existing Username React

I'm trying to create a sign up page where it first iterates through existing accounts and submits when input account is available; otherwise, it returns an error message if just one element matches.
I first tried .map, but it iterates through the entire array and still submits if one value is false. I then tried .find, but still produces the same result. Afterwards, I tried switch, case and could only return the proper outcome with ==. Lastly, I tried .find and .map using .includes but, again, no luck.
function handleSubmit(e) {
e.preventDefault();
accounts.find(acc => {
if (acc.username.includes(formData.username)) {
console.log("taken");
} else {
some post request code
}
How can I create a function that only produces one outcome if one of many elements meets the condition? Thanks for the help
You should assign the function that finds or filters the username to a variable and then create an if statement using that variable.
To return the first matching object in the array of accounts
const matchingAccount = accounts.find(account => account.username.includes(formData.username);
To return an array of matching account objects
const matchingAccounts = accounts.filter(account => account.username.includes(formData.username);

How can i make a guild-side variable using Discord.js

im trying to make a server/guild side variable for my bot (have a variable that has a different value in each server). I dont know how to make that so i really need help... How can i get a variable to have a different value in each server?
You should use a discord.js Collection, which is:
A Map with additional utility methods. This is used throughout discord.js rather than Arrays for anything that has an ID, for significantly improved performance and ease-of-use.
A Map object holds key-value pairs and remembers the original insertion order of the keys. Any value may be used as either a key or a value. Here's a quick demo:
// let's say we had two people: John and Sarah
const people = new Map();
// each of them were a different age
people.set('John', 25); // in this example, 'John' is the key, and 25 is the value
people.set('Sarah', 19); // in this example, 'Sarah' is the key, and 25 is the value
// each person has an individual age
// you can `get()` the key, and it will return the value
console.log(`Sarah is ${people.get('Sarah')} years old.`);
console.log(`John is ${people.get('John')} years old.`);
You can use this type of format to create a collection with each key being a different guild ID, and each value being... whatever you want. Here's an example:
// const { Collection } = require('discord.js');
const guilds = new Collection();
// put some data in an object as the key
guilds.set("Guild ID", {
name: "Guild Name",
welcomeMsg: "Welcome new person!",
welcomeChannel: "...",
blacklistedIDs: ["123456", "67890"],
});
client.on("guildMemberAdd", (member) => {
const guild = guilds.get(member.guild.id); // get the collection element via guild id
if (!guild) return;
// then access all its data!
console.log(`Somebody joined ${guild.name}`);
if (guild.blacklistedIDs.includes(member.id)) return member.kick();
guild.welcomeChannel.send(guild.welcomeMsg);
});
I believe Tin Nguyen posted this idea as a comment, I am just elaborating on that. To achieve what you want, you can use what is known as a "data dictionary" which is basically just a file storing a list of something.
For your specific use case, you can use a simple JSON file to store your variables. For each guild that your bot is in, you can add a new object to a list of objects in a local JSON file called variable.json for example.
Here is an idea of what it might look like:
[
{
"guild": "INSERT GUILD ID",
"value": "INSERT VARIABLE VALUE"
},
]
guild will store the id of the guild, so you can identify the correct value. To get the value stored in value for a certain guild, all you have to do is loop through the JSON file, and find the object with the correct guild ID:
const variables = require("variable.json"); //imports the JSON data
const value; //creates a new variable
for (i = 0; i < variables.length; i++) { //loops through the guilds
if (variables[i].guild === message.guild.id) { //if the IDs are the same...
value = variables[i].value; //...sets "value" to the retrieved value
}
}
This of course relies on the fact that your bot also adds each guild it joins to the list. To do this, you can use the guildCreate event. Documentation for this can be found here.

How to check the value of a dropdown?

I am trying to read (using protractor and BDD) the default values of certain dropdowns. To do this, I have tried several lines of code but none of them works.
Here is the code that I am using, the console.log is not being executed for some reason. Why?
checkDropdownAssignment: function(dropdown,defaultValue) //Function to check the value assigned to a dropdown
{
let texto=[];
$$('* option:checked').each(function(element, index) { // Execute this operation for each element of the website
element.getText().then(function (text) { //Get text of the element in order to compare it with the endpoint afterwards.
texto.push(index.toString()); // Add one more component to the vector
texto[index]=text; // Save the text in a variable visible outside of this function.
console.log(texto[index]);
});
});
},
Thanks in advance.
Try this:
$$('*option:checked').all(by.tagName('option')).getAttribute('label').then(function(value){
for (var i=0; i<value.length; i++){
expect(value).toContain(arayOfExpectedResults[i]);
}
});
Here you get an array with all the labels inside the dropdown and compare them with the expected result, or use the array the way you want.

JSON object update giving strange result

Hi I am updating a json object which has internal array and each object of array has id element. Based on id element I update one of the element which matches the inout id, but it is modifying more than one object. My source code and console logs are given below which will help in understanding the issue.
function
updateUserData(event,id){
var elementName=event.target.name;
console.log('id='+id+', element name='+elementName);
var userData=this.state.user_data;
console.log('User Data before change ='+JSON.stringify(userData));
for(var i=0;i<userData.sports.length;i++){
for(var j=0; j<userData.sports[i].ticket_detail.length;j++){
if(userData.sports[i].ticket_detail[j].id==id){
for(var k=0;k<userData.sports[i].ticket_detail[j].ticket.length;k++){
if(userData.sports[i].ticket_detail[j].ticket[k].paramname==event.target.name){
userData.sports[i].ticket_detail[j].ticket[k].value=event.target.value;
console.log('user data after change ='+JSON.stringify(userData));
this.setState({user_data:userData});
return;
}
}
}
}
}
}
console logs
value=h
id=0, element name=name
User Data before change =
{"total_tickets":3,"total_amount":2124,"htmlid_counter":3,"sports":[{"name":"Badminton","ticket_detail":[{"cat":"Men Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":""},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":0},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":""},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":1},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":""},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":2}]},{"name":"Carrom","ticket_detail":[]}],"tournament_id":1}
user data after change =
{"total_tickets":3,"total_amount":2124,"htmlid_counter":3,"sports":[{"name":"Badminton","ticket_detail":[{"cat":"Men Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":"h"},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":0},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":"h"},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":1},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":"h"},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":2}]},{"name":"Carrom","ticket_detail":[]}],"tournament_id":1}
You can see from the abobe json , even though input id=0, but json object with id 0 , 1 and 2 are modified. Can someone help me to resolve this issue.
You are doing a asynchronous setState at each iterations. that's probably why you are getting a weird result.
You have to build a new array, then, after your array is what you finally want in your state, you can do:
this.setState({ user_data: newArray })
I found the issue. This issue was happening because each element of array was havinv reference to a common element. That was the reason when I was modifying any one of them, all were been modified.

Display content of an Array of Objects with Interpolation in Angular2 Typescript

Application
A simple Search bar and a button where user enters a keyword and the response returned is from a RESTful server (HTTP GET requests)
simplesearch.ts
export class SimpleSearch {
kw: string; // keyword
resp: string; // response from Server
}
simplesearch.service.ts
Has a simple method called searchData which does a HTTP GET request with the user's keyword as a query search. (Code not included for brevity)
simplesearch.component.ts
/*All respective headers and #Component removed from brevity*/
const OUTPUT: SimpleSearch[] = []; // create an array for storing Objects
export class SimpleSearchComponent {
Output = OUTPUT; // define variable for array
constructor(private httpServ: SimpleSearchService, private temp: SimpleSearch) {}
/*Search button on HTML file does this*/
Search(inputVal: string) {
this.temp.kw = inputVal; // store the value of user's input
this.httpServ.searchData(inputVal)
.then(res => this.temp.resp = res); // store the response in temp.resp
// push the Object on the Output Array
this.Output.push({kw: this.temp.kw, resp: this.temp.resp});
}
}
Interpolation Variable
I use Output as an Interpolation Variable for my HTML template. I show the data in an unordered list
<ul>
<li *ngFor="let keyword of Output">
<span>{{keyword.kw}}</span>
</li>
</ul>
Response:
<ul>
<li *ngFor="let answer of Output">
<span>{{answer.resp}}</span> <!-- WHAT TO DO HERE for Array Index-->
</li>
</ul>
Result
I can see the keywords in a list every time a user inputs new keywords but
the responses in the wrong way
How do I pass Indexing with the Interpolation? Or am I thinking wrong?
The easy way out was to create two separate Array<String> for keywords and responses and this works great since I can use the index to delete the contents on the page too but with an Object in an Array I am confused with the key: value representation and the index of the Array (OUTPUT) itself.
The problem lies exactly where developer noticed, this.temp.resp is outside the async function. So when you are pushing items in your Output array, it's always pushing the previous search with the new keyword, therefore you are getting the behavior that the resp is always "one step behind". You can check this to understand this async behavior: How do I return the response from an Observable/http/async call in angular2?
So let's look at the code and explain what is happening. I assume you have initialized 'temp' since it isn't throwing an error on first search, where temp.resp would be undefined unless temp is initialized.
this.httpServ.searchData(inputVal)
// this takes some time to execute, so the code below this is executed before 'this.temp.resp' has received a (new) value.
.then(res => this.temp.resp = res);
// old value of 'temp.resp' will be pushed, or if it's a first search, empty value will be pushed
this.Output.push({kw: this.temp.kw, resp: this.temp.resp});
So how to solve this, would be to move the this.Output.push(... line inside the callback (then), so that the correct values will be pushed to the array.
Also I'd change your model to be an Interface instead of Class. But as to how to change the function and do the assignment inside the callback, I'd also shorten the code a bit and do:
Search(inputVal: string) {
this.httpServ.searchData(inputVal)
.then(res => {
// we are pushing values inside callback now, so we have correct values!
// and 'SimpleSearch' stands for the interface
this.Output.push(<SimpleSearch>{kw: inputVal, resp: res});
});
}
}
This should take care of it that the corresponding keyword will have the corresponding response! :)
PS. Worth noticing here, is that you'd maybe want to display the keyword while we are waiting for the response for that keyword, I ignored it here though and applied the same as you are currently using.

Resources