Parsing a JSON object in node.js - javascript

{"__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})

Related

How to filter and retrieve nested child in Firebase realtime database?

This is a simplified version of the DB structure that I'm working with:
"user" : {
"nhbAQ9p8BrMoAIbJNKvLlXTdiNz2" : {
"log" : {
"-LhMVugmjmIdqwrJSURp" : {
"a" : 25120,
"timeStamp" : 1560312000000,
},
"-Lh_Z9GsJJvlMOpVV9jU" : {
"a" : 19033,
"timeStamp" : 1564718400000,
}
}
}
}
I'm having issues filtering and retrieving the value of "a" with a given user id (e.g. nhbAQ9p8BrMoAIbJNKvLlXTdiNz2) and timeStamp (e.g.1560312000000).
I've tried combinations of orderByChild(), equalTo(), and adding a once() listener to do the task but they've only returned null so far.
The code that I have:
firebase.database().ref('user/' + userID + + '/log').orderByChild('timeStamp').equalTo(targetTimeStamp).once('value').then(function(snapshot){
let userLog = snapshot.val().a
})
where userID is a string and targetTimeStamp is a number.
I checked the doc and a post about orderByChild() but I'm still not sure what is causing it to return null.
This is my first time posting a question, please comment if there's anyway I can make this clearer and any help is much appreciated!
where userID and targetTimeStamp are both strings.
That is the reason nothing is returned. In the database the values of the timeStamp property is a number, and comparing a number to a string never returns a match.
To make the query work, convert the string to a number:
...equalTo(parseInt(targetTimeStamp)).once(...
Aside from that a query against the Firebase Database may potentially have multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
So you need to handle that case too:
firebase.database().ref('user/' + userID + + '/log').orderByChild('timeStamp').equalTo(targetTimeStamp).once('value').then(function(results){
results.forEach(function(snapshot) {
let userLog = snapshot.val().a
})
})

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!

Sorting data in Firebase with JavaScript, how to compare all register in an array of objects?

I found this method, with which I have ordered the hours what I store in my records, I wanted them to be sorted from highest to lowest, but when I test the code, I notice that only two values of the array are compared, which are the first registers.
I've seen other methods of comparison and the logic is the same, what am I doing wrong? I group the messages per user, using the id of the user as key of the array , then I save the rest of data. I do this for retrieve the current messages, since I want show a list of the last currently messages sent.
This is the code:
var ref = new Firebase('https://chatfbexample.firebaseio.com/all-messages');
ref.on("value", function (snapshot) {
var Messages = [];
var value = 0;
snapshot.forEach(function (snap) {
value = snap.val().id;
fecha = snap.val().id;
Messages[value] = [];
Messages[value]['fecha'] = snap.val().fechahora; //I receive a date with the format HH:MM:SS
Messages[value]['texto'] = snap.val().texto;
});
function compare(a, b) {
var time1 = a['fecha'].replace(/:/gi, '1');
var time2 = b['fecha'].replace(/:/gi, '1');
var data1 = parseInt(time1);
var data2 = parseInt(time2);
// alert(time1);
if (data1 > data2)
return -1;
if (data1 < data2)
return 1;
return 0;
}
Messages.sort(compare);
for (var i in Messages) {
console.log("Hour: " + Messages[i]['fecha'] + ' ' + ' Message: ' + Messages[i]['texto']);
}
});
the result is something like this
Hour: 12:11:13 Message: whats'up?
Hour: 11:38:44 Message: p
Hour: 11:49:01 Message: hey?
the second and the third messages are not being compared
an image of my Firebase database
First off it probably would be better for you to save a timestamp from Firebase instead of an actual time, which was probably created on the client side, inside your database. This way you could easily let Firebase handle the sorting.
You would need to use firebase.database.ServerValue.TIMESTAMP to save the exact time at which Firebase received your message inside fechahora.
Following you could simply query all of your messages ordered by their child fechahora.
ref.orderByChild("fechahora").on("value", function (snapshot) {
//Do stuff with your already sorted data
}
If you want your query to have a better performance set the .indexOn property of your node containing all the messages inside your Firebase Database rules to fechahora.
Bonus: If you want your data to be ordered newest to oldest instead of oldest to newest, you just need to use the negative value of the timestamp created by Firebase.
Instead of ordering client-side, you'll be better off asking the server to sort the messages:
ref.orderByChild("fechahora").on(...
Make sure that you define the proper index in your Firebase security rules:
{
"rules": {
"all-messages": {
".indexOn": "fechahora"
}
}
}
Without that the sorting will still work, but will happen on the client instead of the server.

Cannot save object props to parse.com table

I have a form with a textbox title, dropdown menu year and a button. When I click the button, I want to get the values of title and year as properties to an object Movie. Then save them to a table on parse.com. The code below adds a recording to the table with values undefined.
<script>
function saveValues() { // function is appended as onclick to button
var $titleValue = $('#inputTitle').val();
var $select = $('#select');
var $yearValue = $select.val();
var Movie = Parse.Object.extend("Movie");
var movie = new Movie();
// movie.set('title', $titleValue); // Doesn't work. Returns undefined
// movie.set('year', $yearValue); // Doesn't work. Returns undefined
movie.title = $titleValue; // Works
movie.year = $yearValue; // Works
alert(movie.title); // Returns the value
alert(movie.year); // Returns the value
alert(movie); // Returns [object Object]. I was expecting {title: '<SOMETITLE>', year: '<SOMEYEAR>'}
console.log(movie); // This prints a lot of stuff and title and year are there with the respective values.
movie.save()
.then(function(object) {
alert("yay! it worked");
})
}
</script>
Note that when I try to save only the title to the table, it works fine.
Without seeing your full code, I can't guarantee that this will work, but give this a try:
movie.save({
title : $titleValue,
year : $yearValue,
}, {
success: function(movie) {
alert("movie saved successfully with title: " + movie.get("title") +
", and year: " + movie.get("year"));
},
error: function(error) {
alert("error, movie save failed. error code: " + error.code + ", " error.message);
}
});
At the very least you will have a descriptive error message that will tell you what went wrong. Based on the fact that you said it works when you only save the title and not the year, I suspect it may be because your 'year' field in Parse is stored as a number, but you are passing it in as a string (since it came from an HTML form, I'm assuming).
If that doesn't work, I also suspect it may have something to do with appending this function to your button onload rather than as a click or a submit. But that wouldn't explain why it still works if you just leave out the year.
Finally, I wonder if Parse's SDK is confused by the '$' symbol at the beginning of your variable names, but I don't see why that would be the case.
OK, after some time I found out what the problem was. And it was a silly one. It turns out that the value in option was of type 'string'. By adding parseInt() like so: var $yearValue = parseInt($select.val());. And then movie.save({title: titleValue, year: yearValue})..... This way everything works. Initially, I had tried putting key-value pairs in the save() but the year value wasn't the right type.
So note to anyone out there - check your data types!

retrieve unique values for key from parse.com when class has > 1000 objects

In parse I have a class named "TestScore". Each object has a key named "quizName".
I need to get an array of unique "quizName" values. I wrote the below which queries the "TestClass" and loops through the results looking for unique "quizName" values.
At first seemed to do the job. But then I realized that the maximum number of returned objects is 1000. Soon there will be more than 1000 objects stored which means that this method will not guarantee that I end up will all values.
function loadTests(){
//create an array to hold each unique test name as we find them
var uniqueEntries = [];
//query parse to return TestScore objects
var TestScore = Parse.Object.extend("TestScore");
var query = new Parse.Query(TestScore);
query.limit(1000) //added this after realizing that the default query limit is only 100
query.find({
success: function(testScore) {
$(testScore).each(function(index, score) {
//here I loop though all of the returned objects looking at the "quizName" for each
if($.inArray(score.get("quizName"), uniqueEntries) === -1) {
//if the quiz name is not already in the "uniqueEntries" array, I add it to the array
uniqueEntries.push(score.get("quizName"));
}
});
//do stuff with quiznames here...., add them as options in select boxes mostly
}
});
}
I looked at {Parse.Query} notContainedIn(key, values) which looks promising but cant figure out if I can add values to the array as I find them. It seems like I would have to have an array to start with (defeating the whole point.)
This part of the docs "{Parse.Query} Returns the query, so you can chain this call." makes me think I might be able to chain queries together to get what I need, but that doesn't seem very efficient.
How can I retrieve unique values for key "quizName" when my class has > 1000 objects?
I'm sure you're long past this by now, but only way I know of to do it is to use one query after another by using a .skip(#) value for each query. So get 1000, then query again with .skip(1000), concatenate the items from the first list and second, then query again with .skip(2000), etc...
Be aware that I think there's a limit on skip values of 10,000. Don't take my word on that, just pointing you to something that I think is right that you should confirm if you think it applies to your situation.
I eventually found a tutorial online that I was able to modify and came up with the below. This effectively sets the return limit to 10,000 instead of 1,000 and allows setting several different parameters for the query.
My changes could surely be written better, maybe as an options object or similar but it works for my needs.
You can see a working demo here
function getStuff(){
// here we will setup and call our helper functions with callbacks to handle the results
var scheme =['SOTest',true]; // return all objects with value `true` in the `SOTest` column
// var scheme =['descending','createdAt']; // return all objects with sort order applied
// var scheme =''; // or just return all objects
// see `findChunk()` below for more info
var Remark = Parse.Object.extend("Remark");
schemePromise(Remark, scheme).done(function (all) {
console.log('Found ' + all.length+' Remarks');
$.each( all, function(i, obj){
$('#test').append(obj.get('Remark') +'<br>');
});
})
.fail(function (error) {
console.log("error: " + JSON.stringify(error));
});
}
getStuff(); // call our function
// helper functions used to get around parse's 1000 query limit
// raises the limit to 10,000 by using promises
function findChunk(model, scheme, allData) {
// if `scheme` was an empty string, convert to an array
// this is the default and returns all objects in the called class
if(scheme==''){ ['scheme',''] };
// will return a promise
var limit = 1000;
var skip = allData.length;
var findPromise = $.Deferred();
var query = new Parse.Query(model);
// to get all objects from the queried Class then sort them by some column
// pass `scheme` as an array like [ sort method, column to sort ]
if (scheme[0]=='descending') query.descending(scheme[1]);
else if (scheme[0]=='ascending') query.ascending(scheme[1]);
// to limt results to objects that have a certain value in a specific column
// pass `scheme` as an array like [ column name, value ]
else query.equalTo(scheme[0], scheme[1]);
// more options can easily be built in here using `scheme`
query
.limit(limit)
.skip(skip)
.find()
.then(function (results) {
findPromise.resolve(allData.concat(results), !results.length);
}, function (results) {
findPromise.reject(error);
});
return findPromise.promise();
}
function schemePromise(model, scheme, allResults, allPromise) {
// find a scheme at a time
var promise = allPromise || $.Deferred();
findChunk(model, scheme, allResults || [])
.done(function (results, allOver) {
if (allOver) {
// we are done
promise.resolve(results);
} else {
// may be more
schemePromise(model, scheme, results, promise);
}
})
.fail(function (error) {
promise.reject(error);
});
return promise.promise();
}

Categories

Resources