nested javascript queries in parse - javascript

I have the code below. Basically I have 3 nested parse queries. One is getting a number of "followers" and for each follower I am getting a number of "ideas" and for each idea I would like to get that idea creator's name (a user in the user table).
The first two nested queries work but then when i try to get the name of the user (the creator of the idea), that last nested query DOES NOT execute in order. That query is skipped, and then it is executed later in the code. Why is this happening please?
var iMax = 20;
var jMax = 10;
var IdeaList = new Array();
var IdeaListCounter = 0;
var myuser = Parse.User.current();
var Followers = new Parse.Query("Followers");
Followers.equalTo("Source_User",{__type: "Pointer",className: "_User",objectId: myuser.id});
Followers.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
var object = results[i];
var Ideas = new Parse.Query("Ideas");
Ideas.equalTo("objectId_User", {__type: "Pointer",className: "_User",objectId: object.get('Destination_User').id});
Ideas.find({
success: function(results2) {
for (i=0;i<iMax;i++) {
IdeaList[i]=new Array();
for (j=0;j<jMax;j++) {
IdeaList[i][j]=0;
}
}
for (var j = 0; j < results2.length; j++) {
var object2 = results2[j];
var ideausername2 = "";
IdeaListCounter++;
var ideausername = new Parse.Query("User");
ideausername.equalTo("objectId",object2.get('objectId_User').id);
ideausername.first({
success: function(ideausernameresult) {
ideausername2 = ideausernameresult.get("name");
}
});
IdeaList[IdeaListCounter,0] = object2.get('objectId_User').id + " " + ideausername2; //sourceuser
IdeaList[IdeaListCounter,1] = object2.get('IdeaText'); //text
IdeaList[IdeaListCounter,2] = object2.get('IdeaImage'); //image
IdeaList[IdeaListCounter,3] = object2.get('IdeaLikes'); //likes
IdeaList[IdeaListCounter,4] = object2.get('IdeaReport'); //reports

Your nested query is asynchronous.
Check out the answer at the following for guidance:
Nested queries using javascript in cloud code (Parse.com)

Related

Concat in a for loop google app scripts javascript

I'm trying to filter in an array by data in another array using concat in a for loop. The elements of the following code are logging correctly, but the final array is logging an empty array.
function Shipments (){
var app = SpreadsheetApp;
var movementSS = app.getActiveSpreadsheet();
var infoSheet = movementSS.getSheetByName("Update Info");
var orderInfoSheet = movementSS.getSheetByName("Order Info");
var targetSheet = movementSS.getSheetByName("Shipments");
var ShipLogSS = app.openByUrl(URL).getSheetByName("Shipping Details");
var ShipArr = ShipLogSS.getRange(3,1,ShipLogSS.getLastRow(),ShipLogSS.getLastColumn()).getValues().
filter(function(item){if(item[1]!=""){return true}}).
map(function(r){return [r[0],r[1],r[2],r[4],r[10],r[11],r[16],r[18],r[23]]});
var supplierData = orderInfoSheet.getRange(3,6,orderInfoSheet.getLastRow(),1).getValues().
filter(function(item){if(item[0]!=""){return true}});
var supplierList = [];
for (var i in supplierData) {
var row = supplierData[i];
var duplicate = false;
for (var j in supplierList) {
if (row.join() == supplierList[j].join()) {
duplicate = true;
}
}
if (!duplicate) {
supplierList.push(row);
}
}
var supplierFilter = [];
for(var i = 0; i < supplierList.length; i++){
var shipments = ShipArr.filter(function(item){if(item[4]===supplierList[i][0]){return true}});
supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);
}
Any help would be greatly appreciated!
You need to assign the result of concat onto the supplierFilter in order to see the changes in later iterations and in the outer scope.
You can also return the comparison done inside the .filter callback immediately, instead of an if statement - it looks a bit cleaner.
var supplierFilter = [];
for (var i = 0; i < supplierList.length; i++) {
var shipments = ShipArr.filter(function (item) { return item[4] === supplierList[i][0]; });
supplierFilter = supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);

How to set data from an array to another array to improve performance

I'm currently developing a sheet that shows results from a set of data based on some filters but the data loads to slowly when getting the results, I've tried to follow the Best Practices from Google Documentacion with no luck, how can I set an array for the data to load faster?
Below is the code commented with what I've already tried
function realizarBusqueda() {
var inicio = SpreadsheetApp.getActive().getSheetByName("INICIO");
var aux_tags = SpreadsheetApp.getActive().getSheetByName("Aux_Tags");
var data = SpreadsheetApp.getActive().getSheetByName("Data");
var data_lc = data.getLastColumn();
var data_lr = data.getLastRow();
var searchRange = data.getRange(2,1, data_lr, data_lc);
var inicio_lc = inicio.getLastColumn();
inicio.getRange("A8:L1000").clearContent();
inicio.getRange("A8:L1000").clearFormat();
var countRows = inicio.getMaxRows();
inicio.deleteRows(20, (20-countRows)*-1);
if (inicio.getRange("B4").isBlank()) {
inicio.getRange("A8:L1000").clearContent();
inicio.getRange("A8:L1000").clearFormat();
var countRows = inicio.getMaxRows();
inicio.deleteRows(20, (20-countRows)*-1);
SpreadsheetApp.flush();
}
else if ((inicio.getRange("B4").getValue() != "" &&
inicio.getRange("C4").getValue() === "")) {
//filtrado 1
var arrayDatos = searchRange.getValues();
var inicio_fr = 8;
//var row = new Array(11);
for (var j = 2; j <= data_lr; j++) {
//row[j] = new Array(data_lr);
if (aux_tags.getRange("P2").getValue() === arrayDatos[j-2][4]) {
var inicio_fc = 1;
for (var i = 0; i < arrayDatos[j-2].length; i++) {
//row[j][i] = arrayDatos[j-2][i];
var row = arrayDatos[j-2][i];
inicio.getRange(inicio_fr, inicio_fc).setValue(row);
inicio_fc++;
}
inicio_fr++;
}
//inicio.getRange("A8").setValues(row);
}
}
I expect the output to load lots faster, currently what I've tried is commented, the code as-is is working but too slow
I just wanted to update this subject because I figured out myself, see attached the new code with the use of new 2D arrays
...
//filtrado 1
var arrayDatos = searchRange.getValues();
var inicio_fr = 8;
var rows = [];
var row = [];
for (var j = 2; j <= data_lr; j++) {
if (aux_tags.getRange("P2").getValue() === arrayDatos[j-2][4]) {
var inicio_fc = 1;
for (var i = 0; i < arrayDatos[j-2].length; i++) {
row.push(arrayDatos[j-2][i]);
if (i == 11) {
rows.push(row);
row = [];
}
}
}
}
inicio.getRange(8, 1, rows.length, rows[0].length).setValues(rows);
}
Now instead of writing on row at a time, I just write the whole array at once

How to make a javascript function with elementid like argument?

I have an DevExpress Mvc token extension, where the user will insert several items.
Using javascript I send the items to the controller, which is working fine.
My function look like this:
$(function() {
$("#btnSave").click(function () {
var name = window.ComboBox.GetValue();
var i;
var team = new Array();
var tokens = window.tokenBox.GetTokenCollection();
for (i = 0; i < tokens.length; i++) {
team.push(tokens[i]);
}
var s = new Array();
var ss = window.tokenBox2.GetTokenCollection();
for (i = 0; i < ss.length; i++) {
s.push(ss[i]);
}
var w = new Array();
var ww = window.tokenBox3.GetTokenCollection();
for (i = 0; i < ww.length; i++) {
w.push(ww[i]);
}
var o = new Array();
var oo = window.tokenBox4.GetTokenCollection();
for (i = 0; i < oo.length; i++) {
o.push(oo[i]);
}
var t = new Array();
var tt = window.tokenBox5.GetTokenCollection();
for (i = 0; i < tt.length; i++) {
t.push(tt[i]);
}
$.ajax({
type: "post",
url: '#Url.Action("Action","Controller")',
data: { name:name, team:team, s:s, o:o, w:w, t:t },
beforeSend: function () {
window.loadingPanel.Show();
},
success: function (response) {
$("#mainAjax").html(response);
window.loadingPanel.Hide();
}
});
});
});
I want to use a function, to get the items from token and put them in an array (not repetitive code like above), something like this:
function GetTokenItems(token) {
var list = new Array();
var el = document.getElementsById(token);
var tokens = el.GetTokenCollection();
for (var i = 0; i < tokens.length; i++) {
list.push(tokens[i]);
}
return list;
};
This function is not working, error says:
Uncaught TypeError: document.getElementsById is not a function
How can I pass the Id of the tokenBok like argument in a function, or/and what is wrong with my function?
**Edit:**
I made the correction document.getElementById and now I get the error:
Uncaught TypeError: el.GetTokenCollection is not a function
Should be document.getElementById(id):
Returns a reference to the element by its ID; the ID is a string which can be used to identify the element; it can be established using the id attribute in HTML, or from script.
document.getElementById(...)
// ^ without s
I found the answer of my issue, maybe will be helpfull for others!
For Devexpress mvc extensions is enough to use the name of the extension like argument, no need to look for him with document.getElementById, so my function is working like this:
function GetTokenItems(token) {
var list = new Array();
var tokens = token.GetTokenCollection();
for (var i = 0; i < tokens.length; i++) {
list.push(tokens[i]);
}
return list;
};
now I can call this function like this:
var team=GetTokenItems(tokenBox); and is working!!!

Parse.com - Getting 400 Bad Request, Using Inner Queries

I am performing multi-level inner queries but it gives me a 400 Bad Request for the line with the find() function, what have I done wrong?
var EducationVenue = Parse.Object.extend("EducationVenue");
var EducationVenueRoom = Parse.Object.extend("EducationVenueRoom");
var EducationLessonSet = Parse.Object.extend("EducationLessonSet");
var EducationLesson = Parse.Object.extend("EducationLesson");
var eduLessonSetQuery = new Parse.Query(EducationLessonSet);
eduLessonSetQuery.matchesQuery("educationListingId", eduListingQuery);
var eduLessonQuery = new Parse.Query(EducationLesson);
eduLessonQuery.matchesQuery("educationLessonSetId", eduLessonSetQuery);
eduLessonQuery.include('educationVenueRoomId.educationVenueId');
$scope.coursesAtLocations = [];
eduLessonQuery.find({
success: function(coursesAtLocations) {
for (var i = 0; i < coursesAtLocations.length; i++) {
$scope.coursesAtLocations.push(coursesAtLocations[i]);
console.log('c at loc' + coursesAtLocations[i]);
}
}
});
The reason for this is "query has too many nested queries", what is the more convenient workaround for this?

Adding a running sum to a javascript object

I have a javascript object as below
var mydata=[
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":0},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":0},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":0},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":3,"Pnts":2,"CumPnts":0},]
I want to update the object so that CumPnts contains a running points total for each Club as below
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":3},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":4},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":8},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":2},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":6},
{"Club":"Preston","EventNo":3,"Pnts":1,"CumPnts":7},]
Any help would be much appreciated
Here is a function that loops through the list and updates it after it's been added. But I suspect that the events come in one at a time so there could be another function that can look the cumPtns obj and take from that. Here is for the current list.
var cumData = {};
var mydata=[
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":0},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":0},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":0},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":3,"Pnts":2,"CumPnts":0}];
function updateMyData() {
for (var i = 0; i < mydata.length; i++) {
var item = mydata[i];
if(cumData[item.Club] == undefined) {
cumData[item.Club] = {};
cumData[item.Club] = item.Pnts;
} else {
cumData[item.Club] = cumData[item.Club] + item.Pnts;
}
mydata[i].CumPnts = cumData[item.Club];
};
console.log(mydata);
//if you want to return it you can have this line below. Otherwise the object is updated so you'll probably want to do something with it once it's updated. Call back maybe?
return mydata;
}
updateMyData();
The first time it encounters a team it adds it to an array and so does with the corresponding cumPnts, so we can keep track of whether we checked a team earlier or not.
var tmArr = [];
var cumArr = [];
for(var i = 0; i < mydata.length; i++) {
var elm = mydata[i];
var club = elm.Club;
var points = elm.Pnts;
var idx = tmArr.indexOf(club);
if(idx > -1) {
cumArr[idx] += points;
elm.CumPnts = cumArr[idx];
}
else {
elm.CumPnts = points;
tmArr[tmArr.length] = club;
cumArr[cumArr.length] = points;
}
}
jsfiddle DEMO

Categories