Get json array from sub mongoose query - javascript

I have a sub query in mongoose need to get array out of sub query and attach to main json out put/ object.
my first query get user info which contains blocked_users array which is nothing but array of user id's.
i my second query we get profile details of blocker_users array and append to main user object in blocked_users.
var userId = ObjectID(req.body.user_id);
//Get user
newUserModel.findById(userId, function(err, user){
if(err){
utils.getResponse(res, req.url, messages.failure, "");
} else {
var userInfo = {};
var blcked_contacts;
//get users details from blocked contacts userid's array
newUserModel.find({'_id': {$in:user.blocked_contacts}}, function (err,blocked_users) {
if(blocked_users){
//blcked_contacts.push(blocked_users);
console.log(blocked_users);
return;
};
/*else{
blcked_contacts = [];
}*/
});
userInfo['blocked_contacts'].push(blocked_users);
userInfo['user_id'] = user.id;
userInfo['country_code'] = user.country_code;
//userInfo['blocked_contacts'].push(blcked_contacts);
//userInfo['blocked_contacts'] = user.blocked_contacts;
var userData = Array();
}
});

Don't really know what you're looking for. But saw a problem in your code. You've assigned the blocked_users to the blocked_contacts field outside the find method.
Since these calls are asynchronous in nature, it might happen that the assignment takes place even before the documents are fetched from MongoDB. So you should write your assignment statements inside the find methods' callback, just the way Medet did.

Noticed few mistakes in your code like trying to use .push on an object. You cant do
userInfo['blocked_contacts'].push(blocked_users); // incorrect as userInfo is an empty object and you dont have an array defined for userInfo['blocked_contacts']
You probably get cannot push into undefined error for this. So instead do
userInfo['blocked_contacts'] = blocked_users;
Also you have to do this inside the second find() as blocked_users is only available inside it. So your final query should be something like
var userId = ObjectID(req.body.user_id);
//Get user
newUserModel.findById(userId, function(err, user){
if(err){
utils.getResponse(res, req.url, messages.failure, "");
} else {
var userInfo = {};
//get users details from blocked contacts userid's array
newUserModel.find({'_id': {$in:user.blocked_contacts}}, function (err,blocked_users) {
if(blocked_users){
userInfo['user_id'] = user.id;
userInfo['country_code'] = user.country_code;
userInfo['blocked_contacts'] = blocked_users; // assign blocked_users into userInfo
console.log(userInfo) // Your required object
} else {
userInfo['user_id'] = user.id;
userInfo['country_code'] = user.country_code;
userInfo['blocked_contacts'] = []; // assign null array if no blocked users fould
}
});
var userData = Array();
}
});
The result of console.log should be an object like this
{
user_id : "..id of searched user...",
country_code : "..country code of searched user..",
blocked_contacts : [<array containing detais of all blocked users>] // null array if no users found
}

Related

Azure Cosmos DB Stored Procedure With Parameter

I am new to Azure Cosmos Db and I am working on a simple stored procedure (JavaScript) that needs to return a document if the Id is provided. I don't get "no docs found" when I execute the stored procedure. Bellow is my code:
function sample(id) {
var collection = getContext().getCollection();
var query = {
query: "SELECT * FROM c WHERE c.id = \'id\'"
};
// Query documents and take 1st item.
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),query,
function (err, feed, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found', 
// else take 1st element from feed
if (!feed || !feed.length) {
var response = getContext().getResponse();
response.setBody('no docs found');
}
else {
var response = getContext().getResponse();
var body = { id: id, feed: feed[0] };
response.setBody(JSON.stringify(body));
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}```
Queries get automatically scoped to the partition key passed to the stored procedure. So your query is partition key = and id = . When you skip passing the partition key, it is set to undefined as well.
Can you please try to set it via FeedOptions.PartitionKey in .NET or the x-ms-partition-key header?

Unable to retrieve data from Cloud Firestore using queries

I am attempting to retrieve a collection of data from my Cloud Firestore, so that I can arrange the data in a "Bootstrap" Table, displaying the name and the score from the Firestore documents.FireStore Layout Here.
I have created a reference to the user collection and queried this to obtain data, however when I run this it throws an exception "Uncaught ReferenceError: querySnapshot is not defined".
<script>
var usersCollectionRef = db.collection("users"); //Creates a reference to the Users collection
var query = usersCollectionRef.orderBy("score", "desc").limit(10); //Creates a query based on the collection
query.get().then(function(querySnapshot) { //If query is needed
if (querySnapshot.empty) { //Check whether there are any documents in the result
console.log('no documents found');
} else {
querySnapshot.docs.map(function (documentSnapshot) {
var name = documentSnapshot.data().name;
var score = documentSnapshot.data().score;
console.log(name + score);
});
}
});
</script>
My aim is to retrieve all of the documents inside the user collection, order and sort them using the inbuilt .limit and orderBy methods, then store them in an array so that they can be displayed using a "Bootstrap" table.
var query = usersCollectionRef.orderBy("score").limit(10); //Selects the 10 highest scoring player's documents
Note for potential readers: the fist part of the answer corresponds to the initial question of the OP, before it was edited.
You have to put the second part of your code within the then() function, as below.
This is because get() returns "a promise that will be resolved with the results of the query." (see the Ref https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference#get)
var usersCollectionRef = db.collection("users"); //Creates a reference to the Users collection
var query = usersCollectionRef.where("name", "==", "Steeve"); //Creates a query based on the collection
query.get().then(function(querySnapshot) { //Call get() to get a QuerySnapshot
if (querySnapshot.empty) { //Check whether there are any documents in the result
console.log('no documents found');
} else {
querySnapshot.docs.map(function (documentSnapshot) {
//Not necessary to do that -> return documentSnapshot.data();
console.log(documentSnapshot.data().name);
});
}
});
EDIT following your comment:
In case you would have several documents for a given name which hold a different score (in a number field score), you could get the total score like that:
var usersCollectionRef = db.collection("users"); //Creates a reference to the Users collection
var query = usersCollectionRef.where("name", "==", "Steeve"); //Creates a query based on the collection
query.get().then(function(querySnapshot) { //Call get() to get a QuerySnapshot
var score = 0;
if (querySnapshot.empty) { //Check whether there are any documents in the result
console.log('no documents found');
} else {
var data = querySnapshot.docs.map(function (documentSnapshot) {
//Not necessary to do that -> return documentSnapshot.data();
console.log(documentSnapshot.data().name);
score += documentSnapshot.data().score;
});
}
console.log(score);
});
EDIT after edit of the original post
Do like that
var query = usersCollectionRef.orderBy("score", "desc").limit(10); //Creates a query based on the collection
query.get().then(function(querySnapshot) { //If query is needed
if (querySnapshot.empty) { //Check whether there are any documents in the result
console.log('no documents found');
} else {
var nameArray = Array.from(querySnapshot.docs, x => x.data().name);
console.log(nameArray);
var scoreArray = Array.from(querySnapshot.docs, x => x.data().score);
console.log(scoreArray);
}
});
Explanations:
querySnapshot.docs returns "An array of all the documents in the QuerySnapshot." (See Ref: https://firebase.google.com/docs/reference/js/firebase.firestore.QuerySnapshot#docs)
Then you use Array.from() to create the two arrays (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)

Checking data in deep array with includes (Firebase retrieve data JS)

So I am new to the Firebase database and what I like about it is that I don't have to build a whole backend for just storing some simple data. What I am trying to do is pushing data to an array that I like to recieve from firebase. Then after that I would like to check if the email that was filled in, is included in the data from the firebase database. But because it's firebase and it has multiple arrays, objects etc I don't know how to check that. So the flow is: User fills in data, Applications makes a call to the firebase db and the Application is retrieving the current data from firebase. Then the Application will check if the data that is inputed is already there, and if so, will throw an alert that the data is already in the database. If not, the data will be submitted.
Also, I am wondering if this is the right way to retrieve data from the database:
Main.js
function writeUserData() {
var name = document.getElementById("name").value;
var email = document.getElementById("email").value;
firebase.database().ref('/aanmeldingen/').push({
username: name,
email: email,
});
var dbRef = firebase.database().ref().child('/aanmeldingen/');
dbRef.on('value', snapshot => {
const snap = snapshot.val();
const array = [];
array.push(snap);
console.log(array);
const res = array.includes(email);
console.log(res);
console.log(email);
});
}
Output in console
As you can see this returns multiple data. The include function will check on the submitted emailadress. This returns false even I had inputted "info#webpack.com". How can I check the right data object? It has to check all objects under "0" and return in the console if the submitted emailadress is already there.
I haven't tested it yet but i hope you get the idea. Also this is not the most efficient way to do this.
function ifEmailExist(arr,email){
var _t = 0;
for(var x in arr){
for(var y in arr[x]){
if(arr[x][y].email){
if(arr[x][y] === email){
_t++;
}
}
}
}
return _t;
}
Usage:
if(ifEmailExist(arr,"info#webpack.com") > 0){
//do stuff
}
You should use child_added instead of value. Whenever a new node is added in database, child_added will trigger and then you can take action on the data.
var dbRef = firebase.database().ref().child('aanmeldingen');
dbRef.on('child_added', snapshot => {
var username = snapshot.val().username;
var email = snapshot.val().email;
console.log(username);
console.log(email);
});

How to save the result from collection.findone()

i have a simple question and i have read a lot of same issues here, but these are not exact the same or doesn't work for me :-(
I have a REST function called "addevent". The function gets a json input (req) and iterate through the json array to get some IDs to store them in an extra Array. That works perfect!
After that, the function should search in a mongodb for every single id and store some extra informations from this ID (e.g. the stored URL of this ID). With "console.log(result.link)" it works again perfect. But my problem is that, that i need to store this link in an extra Array (urlArray).
So how can i save the result of collection.findone(). I read something about, that findone() doesn't return a document, but a cursor? what does that mean? How do i have to handle that in my case?
That's the code:
exports.addevent = function(req, res) {
var ids = req.body;
var pArray = new Array();
var urlArray = new Array();
var eventName = ids.name;
for(var i in ids.photos) {
photoArray.push(ids.photos[i]);
var id = ids.photos[i]._id;
var collection = db.get().collection('photos');
collection.findOne({'_id':new mongo.ObjectID(id)},function(err, result) {
console.log(result.link);
}
)
}
Many thanks!
-------------------- Update --------------------
Ok, i think that has something to do with the asynch Callbacks. I found an article, but i don't know how to implement it in my case.
http://tobyho.com/2011/11/02/callbacks-in-loops/
And something about "promises" in javascript.
You can save the result of your search doing something like:
var foundPhoto = collection.find({_id':new mongo.ObjectID(id)}, function(err, photo){
if(!err){
return photo;
} else {
console.log(err)
return null;
}
});
This way you get the return statement of your query in the "photo" variable.

Parse.com get users from subquery in other class Cloud Code

I have the class Friends on Parse:
Class Friends{
"from" : Pointer(_User)
"to" : Pointer(_User)
"allowSee" : Boolean
"block" : Boolean
"createdAt" : Date
"updatedAt" : Date
}
I have a Parse.Query where I get my friends, but this is Class Friends not class User. I try do a cicle for get the users in el field "from" but the array users return void
var user = Parse.User.current();
var me = {__type: 'Pointer',className: '_User', objectId: user.id}
var qFriends = new Parse.Query("Friends");
qFriends.equalTo("to", me);
qFriends.equalTo("allowSee", true);
qFriends.find().then(function(results){
for (i = 0; i < results.length; i++) {
var uFriendId = results[i].get("from").id;
var getUserById = new Parse.Query("_User");
getUserById.equalTo("objectId", uFriendId);
getUserById.first({
success: function(user) {
users.push(user);
},
error: function(error){
console.log(error);
}
})
}
return users;
}).then(function(friends){
response.success(friends);
}, function(error){
response.error();
});
Do exist way of get users by array of objectIds?, example:
var from =["f8dfg3","32fsg5s","43t4gsd"];
var arrUsers = getUser(from); // return array of PFUser with objectId in array from
Thanks,
Because your Friends class keeps pointers to users, there is a good way, in a single step, to eagerly fetch the related users. Before running the query, add:
qFriends.include("from");
qFriends.include("to");
Upon completion, the related users will be fetched, so you can get at them as follows:
qFriends.find().then(function(results){
for (i = 0; i < results.length; i++) {
var friend = results[i];
var fromUser = friend.get("from");
var toUser = friend.get("to");
// these will be fetched, so you can say things like:
console.log(fromUser.username);
// and so on
Incidentally, there's no need to build a pointer from the current user to qualify the query, the current user will do just fine as follows:
qFriends.equalTo("to", Parse.User.current());
Also, your goal should be covered with just the include() advice above, but at some point you might need to query the related objects in the results block the way your original post code attempts. The OP code makes two mistakes there: (1) you can just fetch(result.get("from")), the object -- no need to extract the objectId and call either get() or first() as you do. (2) all of those functions just named are asynchronous. The loop that launches them will terminate before any of them begin, so the line return users; will necessarily return nothing. The correct approach is to fill an array with the fetch()-returned promises and then return a new promise from Parse.Promise.when(fetchPromises);

Categories