Trying to make a robloxsearch command with RBLX Api - javascript

I am trying to use ROBLOX's API to make a ;rs command but it isn't going so well.
Using request-promise I tried searching and it brought me this error:
SyntaxError: Unexpected token o in JSON at position 1
I have reviewed questions on here before and answered some. If this helps, I am using discord.js-commando for my command handler.
Here is the part the error is coming from:
let editMsg = await msgObject.reply(
":triumph: Finding ROBLOX Account, give me a second!"
);
let rs = await request({
uri: `https://users.roblox.com/v1/users/search?keyword=${idk}&limit=10`,
simple: false,
json: true
});
if (rs.userFacingMessage == "Something went wrong"){
if(rs.code == 5){
editMsg.edit("Sorry 😣, We couldn't process your search! The username you provided has been filtered!");
}
if(rs.code == 6){
editMsg.edit("Sorry 😣, We couldn't process your search! The username you provided is too short!");
}
}else {
let user = JSON.parse(rs)
msgObject.reply(user)
}
Here is a PasteBin link if you need to see the whole run() method.

request-promise with the option json: true automatically parses the JSON string in the response. It means your variable rs is already an object, not a JSON string.
The JSON.parse() method parses a JSON string, so when you try to parse an object, Node.js converts it to a string first ([object Object]). The first character is [ which is valid JSON, but the second one (the letter o) is not, so you receive a SyntaxError: Unexpected token o in JSON at position 1.
Try it out below:
const rs = {
previousPageCursor: null
}
try {
console.log(JSON.parse(rs))
} catch (error) {
console.log(error.message)
}
The API endpoint at https://users.roblox.com/v1/users/search?keyword=${idk}&limit=10 returns an object, so you can't simply send it as-is in a reply. You can use JSON.stringify() to create a string from that object, or you can get an array of users from rs.data.
If you want to return a single user, you can either grab the first item (rs.data[0]) from that array, or use the find() method to find one that matches your keyword:
} else {
const user = rs.data[0]
msgObject.reply(`\`\`\`${JSON.stringify(user, null, 2)}\`\`\``)
}
} else {
const user = rs.data.find((u) => u.name === idk)
msgObject.reply(`\`\`\`${JSON.stringify(user, null, 2)}\`\`\``)
}
PS: Next time when you don't want to be rude, don't write "Not trying to be rude but I want an answer [...]"

Related

How do I use the Java Script JSON.parse() function exactely to display the text flat?

I tried using the parse function but it quite didn't work the way I wanted it to work. This is my code to load a .json file and print it into the terminal.
const fs = require('fs')
function loadJSON(filename = ''){
return JSON.parse(
fs.existsSync(filename)
? fs.readFileSync(filename)
: '""'
)
}
data = loadJSON('test.json')
console.log(data)
But the output in the console was:
{
name: 'Frederik Message File',
Version: 'Frederik Support Asisstant',
messages: {
'21.01.2021': { name: 'Frederik', message: "I don't know what to say..." },
'22.01.2021': { name: 'Frederik', message: 'What am I supposed to do?' }
}
}
But I wanted it all to be on the same line, is that even possible?
When you log an object or array, the console may well try to pretty it up - and, for example, display key-value pairs on separate lines. If you want to display it all on one line, and the source file has the text all on one line, then just don't JSON.parse it, and display the plain text:
function loadJSON(filename = ''){
return fs.existsSync(filename)
? fs.readFileSync(filename)
: '""'
}
If the source file has the text spread out over multiple lines, you can parse it into an object, then turn it back into a string without extra spacing:
function loadJSON(filename = ''){
return JSON.stringify(JSON.parse(
fs.existsSync(filename)
? fs.readFileSync(filename)
: '""'
));
}

delete user from json table in js

So I'm a beginner to js and I have a table of users in a json file and I'm making an account delete feature. I have a find set up to find the user and it works fine but I can't figure out how to make it delete the user from the file, any help would be appreciated!
Json:
{
"users": [
{
"name": "ImBattleDash",
"Id": "780748c5d4504446bbba3114ce48f6e9",
"discordId": "471621420162744342",
"dateAdded": 1548295371
}
]
}
JS:
function findJson() {
fs.readFile('./linkedusers.json', 'utf-8', function (err, data) {
if (err) message.channel.send('Invalid Code.')
var arrayOfObjects = JSON.parse(data)
let findEntry = arrayOfObjects.users.find(entry => entry.discordId == myCode)
let linkEmbed = new Discord.RichEmbed()
.setTitle('Account unlinked!')
.setDescription('Link your account by friending "BattleDash Bot" on Fortnite and then input the code you get messaged by typing "!link <code>"!')
.setColor('#a900ff');
message.channel.send({embed: linkEmbed});
})
}
EDIT: Not sure if it's an array or a table I don't know a lot about json
You need to use:
Array#find to find a given user by some given criteria.
Array#indexOf to get the index of the found user in users
Array#splice to drop one element starting from the index given by Array#indexOf:
const input = {
"users": [
{
"name": "ImBattleDash",
"Id": "780748c5d4504446bbba3114ce48f6e9",
"discordId": "471621420162744342",
"dateAdded": 1548295371
}
]
}
const removeUser = (criteria, users) =>
users.splice (users.indexOf (users.find (criteria)), 1)
removeUser (
({ Id, discordId }) =>
Id == '780748c5d4504446bbba3114ce48f6e9'
&& discordId == '471621420162744342',
input.users
)
// Output: 0 <-- User has been removed!
console.log(input.users.length)
About persisting the change, it's just about calling JSON.stringify (input) and then just write the contents to the desired output file. See this other Q&A: Writing files in Node.js
With great help from Cat and Matias I came up with this code that works!
function findJson() {
fs.readFile('./linkedusers.json', 'utf-8', function (err, data) {
if (err) message.channel.send('Invalid Code.')
var arrayOfObjects = JSON.parse(data)
let findEntry = arrayOfObjects.users.find(entry => entry.discordId == myCode)
const input = arrayOfObjects;
const removeUser = (criteria, users) =>
users.splice (users.indexOf (users.find (criteria)), 1)
removeUser (
({ Id, discordId }) =>
Id == findEntry.Id
&& discordId == findEntry.discordId,
input.users
)
console.log('unlinked')
fs.writeFile('./linkedusers.json', JSON.stringify(arrayOfObjects, null, 4), 'utf-8', function(err) {
if (err) throw err
console.log('Done!')
})
let linkEmbed = new Discord.RichEmbed()
.setTitle('Account unlinked!')
.setDescription('Link your account by friending "BattleDash Bot" on Fortnite and then input the code you get messaged by typing "!link <code>"!')
.setColor('#a900ff');
message.channel.send({embed: linkEmbed});
})
}
Here's a quick tutorial for you:
"Users" would be either an array (using []) or a javascript object (using {}), your choice. There won't be any actual tables unless you use a database instead of a JSON file (although if your JSON expression is as simple as your example, you could almost think of it as a table.) -- And actually, a third option would be to use the javascript Map type, which is like a beefed-up object, but I won't address that here.
While using an array would make it a bit easier to retrieve a list of data for all users (because arrays are simpler to iterate through), using an object would make it considerably easier to retrieve data for a single user (since you can directly specify the user you want by its key instead of needing to loop through the whole array until you find the one you want.) I'll show you an example that uses an object.
The individual user in your sample code is an example of a javascript object. JSON lets you convert an object to a string (for storage, I/O, and human readability) and back to an object (so javascript can understand it). You use the JSON.stringify() and JSON.parse() methods, respectively for these conversions. The string has to be JSON-formatted or this won't work, and your example is almost in JSON format.
To comply with JSON formatting, you could structure a Users object as follows. (Of course we're looking at the stringified version because mere humans can't easily read an "actual" javascript object):
"Users": { // Each individual user is a property of your users object
"780748c5d4504446bbba3114ce48f6e9": // The Id is the key in the "key/value pair"
{ // The individual user object itself is the value in the key/value pair
// Id is duplicated inside user for convenience (not necessarily the best way to do it)
"id": "780748c5d4504446bbba3114ce48f6e9",
"name": "ImBattleDash", // Each property of the user is also a key/value pair
"discordId": "471621420162744342", //Commas separate the properties of an object
"dateAdded": "1548295371" // All property values need double quotes for JSON compatibility
}, // Commas separate the properties (ie the individual users) of the users object
"446bbba3114ce48f6e9780748c5d4504": // This string is the second user's key
{ // This object is the second user's value
"id": "446bbba3114ce48f6e9780748c5d4504",
"name": "Wigwam",
"discordId": "162744342471621420",
"dateAdded": "1548295999"
}
}
Once you retrieve the string from storage, you convert it to an object and delete a user as follows. (This is broken down into more steps than necessary for clarity.):
let usersObject = JSON.parse(stringRetrievedFromFile);
let userId = "780748c5d4504446bbba3114ce48f6e9";
let userToModifyOrDelete = usersObject[userId];
delete userToModifyOrDelete;
To change the user's discordId instead, you would do:
let discordId = userToModifyOrDelete.discordId; // Not necessary, just shows how to retrieve value
let newDiscordId = "whateverId";
userToModifyOrDelete.discordId = newDiscordId;
And you'd convert the object back into a string to store in your file with:
JSON.stringify(usersObject);
Hopefully that's almost all you need to know about JSON!

Get first word of string inside array - from return REST

I try get the sessionid before REST function, but in the case if I does not convert toString(); show only numbers (21 22 2e ...).
See this image:
1º:
Obs.: Before using split.
!!xxxxxxx.xxxxx.xxxxxxx.rest.schema.xxxxResp {error: null, sessionID: qdaxxxxxxxxxxxxxj}
My code:
var Client = require('./lib/node-rest-client').Client;
var client = new Client();
var dataLogin = {
data: { "userName":"xxxxxxxx","password":"xxxxxxxx","platform":"xxxxx" },
headers: { "Content-Type": "application/json" }
};
client.registerMethod("postMethod", "xxxxxxxxxxx/login", "POST");
client.methods.postMethod(dataLogin, function (data, response) {
// parsed response body as js object
// console.log(data); all return, image 1
// raw response
if(Buffer.isBuffer(data)){
data = data.toString('utf8'); // if i does not convert to string, return numbers, see image 1..
console.log(data); //all inside image 2, and i want just value from sessionid
var output = data;
var res = output.split(" "); // using split
res = res[4].split("}", 1);
}
console.log(res); //image 3
});
I tested with JSON.parse and JSON.stringify and it did not work, show just 'undefined' for all. After convert toString();, And since I've turned the values ​​into string, I thought of using split to get only the value of sessionid.
And when I used split, all transform to array and the return is from console.log(data), see image 2:
2º:
Obs.: After use split and convert to array automatically.
And the return after use split is with the conditions inside my code:
3º:
And the return after use split is with the conditions inside my code:
[ 'bkkRQxxxxxxxxxxxxx' ]
And I want just:
bkkRQxxxxxxxxxxxxx
I would like to know how to solve this after all these temptations, but if you have another way of getting the sessionid, I'd be happy to know.
Thanks advance!
After converting the Buffer to a string, remove anything attached to the front with using data.substr(data.indexOf('{')), then JSON.parse() the rest. Then you can just use the object to get the sessionID.
if(Buffer.isBuffer(data)){
data = data.toString('utf8');
data = data.substr(data.indexOf('{'));
obj = JSON.parse(data);
console.log(obj.sessionID);
}
EDIT:
The issue you are having with JSON.parse() is because what is being returned is not actually JSON. The JSON spec requires the properties to be quoted ("). See this article
If the string looked like this, it would work: {"error": null, "sessionID": qdaxxxxxxxxxxxxxj}
Because the json is not really json, you can use a regular expression to get the info you want. This should get it for you.
re = /(sessionID: )([^,}]*)/g;
match = re.exec(data);
console.log(match[2]);
EDIT 2: After fully reading the article that I linked above (oops haha), this is a more preferable way to deal with unquoted JSON.
var crappyJSON = '{ somePropertyWithoutQuotes: "theValue!" }';
var fixedJSON = crappyJSON.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": ');
var aNiceObject = JSON.parse(fixedJSON);

Parsing a JSON object in node.js

{"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"}
{"__v":0,"_id":{"$oid":"55ef49dd5d610eab18719deb"},"admin":true,"email":"emaple2#gmail.com","last_login":"12:25:24 AM","name_surname":"user2","password":"qwerty123"}
{"__v":0,"_id":{"$oid":"55f0173bb3322bf560724fd1"},"admin":true,"email":"emaple3#gmail.com","last_login":"10:25:24 AM","name_surname":"user3","password":"qwerty123"}
Hello, I working in nodeJS file and there I have a collection of JSON objects and I would like to make a search through it. For each user from this list I need to compare the field "last_login" .
I am new to nodeJS can someone help? Thank you!
This is what i have tried:
User.find({}, {last_login: }, function(err, docs) {
if (err) {
return res.json({ success: false, message: 'Failed to display last logins.' });
}
docs.forEach(function(doc, index) {
res.json({success: true, message: 'time of last login', last_login: doc.last_login});
})
//res.json(users);
});
});   
Where last_login is a field in the User object and basically I need to iterate over all users in the db and extract only the last_login and display in in the response.I don’t know what value to put in the find() inside the curly braces
this is the part where I am stuck
I’ve slightly changed the function and it returns a JSON object containing the info about one user that is matched with the search query. The problem is, the console displays the result, as a whole object, although I want to get only a specific key value pair and namely last_login: value
function searchByUserName(name_surname) {
    return list.filter(function(user) {
        return user.name_surname === name_surname;
    });
}
var a = searchByUserName('user1');
for (last_login in a ) {
  if (a.hasOwnProperty(last_login)) {
    console.log("last_login" + "=" + JSON.stringify(a[last_login]))
  }
}
Can you tell me please, what change to make in order to get only the last_login key
here is a sample result from the console.log() that I receive:
last_login={"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"}
although I want last_login = “last_login”: 11:25:24 AM
Assuming it's an array of objects like bellow.
var users = [{"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"},
{"__v":0,"_id":{"$oid":"55ef49dd5d610eab18719deb"},"admin":true,"email":"emaple2#gmail.com","last_login":"12:25:24 AM","name_surname":"user2","password":"qwerty123"},
{"__v":0,"_id":{"$oid":"55f0173bb3322bf560724fd1"},"admin":true,"email":"emaple3#gmail.com","last_login":"10:25:24 AM","name_surname":"user3","password":"qwerty123"}];
you can create a function like bellow
function searchByLastLogin(last_login) {
return users.filter(function(user) {
return user.last_login === last_login;
});
}
console.log(searchByLastLogin("12:25:24 AM"));
console.log(searchByLastLogin("10:25:24 AM"));
console.log(searchByLastLogin("11:25:24 AM"));
It will retrun a array of users whose last_login will match to given parameter last_login.
Update
What I understood from your comment bellow, you want last logins of every user.
For that you can do something like bellow
var last_logins = users.map(function(user){
return user.last_login;
});
console.log(last_logins); //prints [ '11:25:24 AM', '12:25:24 AM', '10:25:24 AM' ]
References
filter | map
I don’t know what value to put in the find() inside the curly braces this is the part where I am stuck
If I understand correctly, you only want to get the last_login field for the user model, and that's what you're struggling with ?
According to the documentation, this should work if you only want to get that field :
User.find({}, {last_login:1, _id:0})

How can I get the first error message from a list of possibly more than one?

I have error messages that appear in the following format:
{
"message":"The request is invalid.",
"modelState":{
"model.ConfirmPassword":["The password and confirmation password do not match."]
}
}
{
"message":"The request is invalid.",
"modelState":{
"model.Email":["The Email must be at least 10 characters long."],
"model.ConfirmPassword":["The password and confirmation password do not match."]
}
}
I know how to get the modelState but how can I get the first message field in the
modelState when that field could be different each time?
What I would like in the first instance is to get the message: "The password and confirmation password do not match."
And in the second instance the message: "The Email must be at least 10 characters long."
You can iterate through all object properties using Object.keys or method hasOwnProperty
for (var k in modelState) {
if (modelState.hasOwnProperty(k)) {
var error_message = modelState[k][0];
// k => "model.Email"
// error_message => "The Email must be at least 10 characters long."
}
}
Most up-to-date browsers support the Object.keys method
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
You can use that to get an array from your modelState that'll return ["model.Email", "model.ConfirmPassword", ... ] in each case.
Then just get the first item from that return array, and call it, so something along the lines of:
var keys = modelState.keys;
var firstError = modelState[keys[0]];
(I haven't tested that syntax, but it's something along those lines)
(note that "first item" might be a little arbitrary, I'm not sure it's guaranteed the order in which the keys will be returned, although in practice I expect you'd find it pretty reliable)
Based on the fact that JS object keys are unordered by nature I'd suggest refactoring your modelState response (you have array as value anyway):
var response = {
"message":"The request is invalid.",
"modelState": {
"errors": ["Bad email", "Bad password"]
}
}
console.log( response.message, response.modelState.errors[0] );
V2:
Based on the fact that JS object keys are unordered by nature, you can add a defined error priority order.
var response = {
"message":"The request is invalid.",
"modelState":{
"model.Email":["The Email must be at least 10 characters long."],
"model.ConfirmPassword":["The password and confirmation password do not match."]
}
}
var priorities = ["model.Email", "model.ConfirmPassword"];
var selectedError = null,
idx = 0;
do {
selectedError = response.modelState[ priorities[ idx ] ];
selectedError = selectedError ? selectedError[0] : null;
idx++;
} while ( !selectedError && idx < priorities.length );
console.log( selectedError || 'Unknown error' );
http://jsfiddle.net/A2dA9/

Categories

Resources