parse server: exclude relation from query javascript sdk - javascript

i am trying to query a class of users which contains a relation column called "blocking" which contains a list of user objects from the same class
when i try to query all users i would like to query which is not present in this relation column
i did the following
var currentUser = Parse.User.current();
var relation = currentUser.relation('blocking')
query.doesNotExist(relation);
query.find().then((users)=>{
for (let i = 0; i < users.length; i++) {
let object = users[i];
console.log(object)
}
}, (error) => {
console.log(error);
});
but it did not work
any help will be appreciated

I managed to do it myself
at first i query the relation and store a list of blocked ids in an array
var currentUser = Parse.User.current();
var relation = currentUser.relation("blocking");
relation.query().find().then(blockedusers=>{
var blockedIds = []
for (var i = 0; i<blockedusers.length; i++){
blockedIds.push(blockedusers[i].id)
}
})
after that i moved the whole query inside the relation find and do (not contained in) this array like the following
query.notContainedIn("objectId", blockedIds)
that solved my problem
thanks

Related

Running ContactsApp.getContact(email) inside a loop causes timeout

I'm creating a GAS for Gmail.
The first part of this script is collecting all recipients and senders from a thread object from the GmailApp. No problem there, except I'm just left with an array of strings with the "full name <email>" syntax.
Secondly, I want to create a card for each contact email, by first looking up the contact object inside the ContactsApp. This however causes the script to time out, even though logs show it is able to fetch the contacts.
I've tested 2 alternatives:
get all contacts with ContactsApp.getContacts() and there's no timeout.
look up a single contact with CotnactsApp.getContact(email)an no timeout either.
// TEST 1: Get All Contacts
var allContacts = ContactsApp.getContacts();
// TEST 2: Get one contact
var testContact = ContactsApp.getContact("test#email.com");
// TEST 3: Loop over and get contacts
var threadContacts = [];
for (var i = 0; i < participants.length; i++) {
var email = participants[i].split("<")[1].split(">")[0];
var contact = ContactsApp.getContact(email);
threadContacts.push(contact)
}
So I'm a bit unclear here as to the intended usage. Should I go for option 1 and load all the contacts on the client side and iterate through these? Or is it intended to look for a contact each time I need to get the data? Doesn't loading all contact risks loading a gazillion contacts (should someone have so many?). It seems cumbersome.
I couldn't see any guidelines on the documentation.
You want to retrieve the contact object by searching the emails.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
In this answer, the contact objects are retrieved by searching the emails from ContactsApp.getContacts(). This method is also mentioned in your question.
Flow:
The flow of this sample script is as follows.
Create an array by retrieving email from "full name <email>".
Retrieve all contacts.
Retrieve the contact object by searching the emails from all contacts.
Sample script:
In this case, it supposes that participants is an array like ["full name <email1>", "full name <email2>",,,].
// Retrieve email address from "full name <tanaike#hotmail.com>" in participants and put them to an array.
var convertedParticipants = participants.map(function(e) {return e.split("<")[1].split(">")[0]});
var allContacts = ContactsApp.getContacts();
// Here, the contact objects are retrieved by searching the emails.
var results = allContacts.reduce(function(ar, c) {
var emails = c.getEmails();
if (emails.length > 0) {
// Retrieve email addresses from a contact object and put them to an array.
var addresses = emails.map(function(e) {return e.getAddress()});
// When the emails of "convertedParticipants" are included in the contact object, the object is put to an array.
if (convertedParticipants.some(function(f) {return addresses.indexOf(f) != -1})) {
ar.push(c);
}
}
return ar;
}, []);
When above script is run, you can see the searched contact objects in results as an array.
References:
getEmails()
getAddress()
reduce()
some()
If I misunderstood your question and this was not the direction you want, I apologize.
Added:
When var results = allContacts.reduce(function(ar, c) {###}, []); is modified using the for loop, it becomes as follows.
Script:
var results = [];
for (var i = 0; i < allContacts.length; i++) {
var emails = allContacts[i].getEmails();
if (emails.length > 0) {
var addresses = [];
for (var j = 0; j < emails.length; j++) {
addresses.push(emails[j].getAddress());
}
var f = false;
for (var j = 0; j < convertedParticipants.length; j++) {
if (addresses.indexOf(convertedParticipants[j]) != -1) {
f = true;
break;
}
}
if (f) {
results.push(allContacts[i]);
}
}
}

Updating the value of an object inside a loop using javascript

I'm currently facing a difficulty in my codes.
First i have an array of objects like this [{Id:1, Name:"AML", allowedToView:"1,2"}, {Id:2, Name:"Res", allowedToView:"1"}...] which came from my service
I assign it in variable $scope.listofResource
Then inside of one of my objects I have that allowedToView key which is a collection of Id's of users that I separate by comma.
Then I have this code...
Javascript
$scope.listofResource = msg.data
for (var i = 0; i < msg.data.length; i++) {
First I run a for loop so I can separate the Id's of every user in allowedToView key
var allowed = msg.data[i].allowedToView.split(",");
var x = [];
Then I create a variable x so I can push a new object to it with a keys of allowedId that basically the Id of the users and resId which is the Id of the resource
for (var a = 0; a < allowed.length; a++) {
x.push({ allowedId: allowed[a], resId: msg.data[i].Id });
}
Then I put it in Promise.all because I have to get the Name of that "allowed users" base on their Id's using a service
Promise.all(x.map(function (prop) {
var d = {
allowedId: parseInt(prop.allowedId)
}
return ResourceService.getAllowedUsers(d).then(function (msg1) {
msg1.data[0].resId = prop.resId;
Here it returns the Id and Name of the allowed user. I have to insert the resId so it can pass to the return object and it will be displayed in .then() below
return msg1.data[0]
});
})).then(function (result) {
I got the result that I want but here is now my problem
angular.forEach(result, function (val) {
angular.forEach($scope.listofResource, function (vv) {
vv.allowedToView1 = [];
if (val.resId === vv.Id) {
vv.allowedToView1.push(val);
I want to update $scope.listofResource.allowedToView1 which should hold an array of objects and it is basically the info of the allowed users. But whenever I push a value here vv.allowedToView1.push(val); It always updates the last object of the array.
}
})
})
});
}
So the result of my code is always like this
[{Id:1, Name:"AML", allowedToView:"1,2", allowedToView:[]}, {Id:2, Name:"Res", allowedToView:"1", allowedToView:[{Id:1, Name:" John Doe"}]}...]
The first result is always blank. Can anyone help me?
Here is the plunker of it... Plunkr
Link to the solution - Plunkr
for (var i = 0; i < msg.length; i++) {
var allowed = msg[i].allowedToView.split(",");
msg[i].allowedToView1 = [];
var x = [];
Like Aleksey Solovey correctly pointed out, the initialization of the allowedToView1 array is happening at the wrong place. It should be shifted to a place where it is called once for the msg. I've shifted it to after allowedToView.split in the first loop as that seemed a appropriate location to initialize it.

sails.js waterline query result from multiple table in database

I have a database with two tables: 'GroupTable' & 'ItemTable'. GroupTable stores the group information such as group name etc. The ItemTable stores the item information as well as which group they belong to. Here's the thing, i am not using foreign key for some reason which i will not explain.
GroupTable: id, name, code
ItemTable: id, name, code, group
The ItemTable also stores the group, differentiated by group='-1'. So what i did was: Find all items in ItemTable with 'group = -1', get the codes of all the items, then filter the GroupTable and find all groups that has codes from the result. Because i need the group names of those groups which are in the ItemTable.
var grp = -1;
$.post("ItemTable/getItems", {group:grp}, function(result){
if(!result.error){
var count = result.data.length;
var data = result.data
var codes = new Array;
for (var i=0; i<count; i++) {
groups.push(data[i].code);
}
$.post("GroupTable/getItem", {code:codes}, function(result2) {
if (!result2.error){
var grpCount = result2.data.length;
var grpData = result2.data;
for (var i=0; i<grpCount; i++){
var name = grpData[i].name;
//DO SOMETHING WITH THE NAME HERE
}
}
}
}
}
Is there anyway i can achieve the same result using only a single post? Or am i looking at this wrongly and i should be editing my getItems function in my controller instead? Currently i am using 'TableItem.find(queryItem).exec()', how should i be writing my code to fit what i am trying to achiveve?
And yes let's assume for some reason i am not able to use foreign key, and that my code will ensure the 'code' is unique in GroupTable.
EDIT:
I am unable to copy and paste as i am working in an offline environment. I am using a MVC model, the code above are the codes for my view. As for the function 'getItems' in my controller, this is the code in my controller(summarized as i have to type this out)
getItems: function(req, res){
var id, name;
(typeof(req.params.id) === 'undefined') ? id=req.body.id : id=req.params.id;
(typeof(req.params.name) === 'undefined') ? name=req.body.name : name=req.params.name;
var queryItem = {
id: id,
name: name
};
// there is more than just id and name, as i did not type everything out
for (var propertyName in queryItem) {
if (queryItem[propertyName] == null){
delete queryItem[propertyName];
}
}
ItemTable.find(queryItem).exec(function(err, items){
if (err)
red.json({"error":err, data:null});
else
res.json({"error":null, data: items});
});

Do a query for every loop item and wait for result

I am making a CloudCode function that returns all users that are matching to my settings. In this function I am looping through a list of users and I need to get their settings in order to see if I should return them. The only problem is that the loop doesn't wait for the query to finish.
How can I get the Settings object for every user in the loop, check if the settings are correct and then push them in an array and return the array when the loop has finished?
The code I am using now:
for (var i = 0; i < connectResults.length; i++) {
var connect = connectResults[i];
for (var j = 0; j < matchResults.length; j++) {
var match = matchResults[j];
if (connect.get("sendBy").id == match.id) {
var indexOf = matchResults.indexOf(match);
matchResults.splice(indexOf, 1);
} else if (connect.get("receivedBy").id == match.id) {
var indexOf = matchResults.indexOf(match);
matchResults.splice(indexOf, 1);
}
if(typeof match.get("settings") != 'undefined') {
var settingsQuery = new Parse.Query("Settings");
settingsQuery.equalsTo("objectId",match.get("settings").id);
settingsQuery.find({
success: function(setting) {
console.log(match.get("username") + " " + setting.get("radius"));
}
});
}
}
}
response.success(matchResults);
Instead of querying all users and attempting to match their settings, I would instead query all users using the setting as a query constraint. In other words, tell the database that you want it to return all the users with the right settings.
var usersQuery = new Parse.Query("Users");
//Below, "settings" is the column name in your Users table
usersQuery.equalTo("settings", /* Settings value you are matching */);
usersQuery.find({
//...
});
You might need a containedIn query if there are multiple setting possibilities. See the docs for an example: https://parse.com/docs/js/guide#queries-query-constraints
Good luck! :)

Autocomplete javascript

I have some problem in crating an autocomplete search box. I have a mongodb collection in which there are photos object with name, description, path and so on. Now, I created a route /searchbox, where the box is displayed in the browser. Every time that the user press a key, a get request to the route /autocomplete/:query is made. The autocomplete route will search in the collection for all the objects where the name, the description or the keywords fields starts with the give query. Then it return a json object containing all the strings that will be put into a datalist in the view. The problem is that I can't create that json array, I tried to create a json object with a field containing an array, and at every iteration on the found array returned by the find function, I get the field name and push it into the array, but nothing is added... here my code:
exports.autoComplete = function(req, res) {
var PhotoAlbum = db.model('PhotoAlbum', schemas.PhotoAlbumSchema);
var regexp = "^"+req.params.query;
var suggestions = {suggestion: []};
var strings = "";
var arrayStrings = [];
PhotoAlbum.find({name: new RegExp(regexp,"i")}, function(err, found) {
if(err) throw handleError(err);
for(obj in found) {
var name = found[obj].name;
suggestions.suggestion.push(name);
strings += name + "|";
}
});
}
Thank you
That looks like Mongoosejs with MongoDB.
IF it is, in that case, its not returning an object at "found". "found" is a collection that is an array already in which you would iterate through it like so:
for(var i = 0; i < found.length; i++) {
console.log(found[i]);
// your code
}

Categories

Resources