Parse query to print all results in a given time frame - date

I would like to create a query that will allow a user to type in a starting date, and print out all records of a table from that date until the current time. I keep getting "Error 102: invalid field type for find". Any suggestions?
function billingReport(){
startDate = new Date(document.getElementById("startDate").value);
var caseList = Parse.Object.extend("Cases");
var query = new Parse.Query(caseList);
query.greaterThanOrEqualTo("createdAt", "startDate");
query.find({
success: function(results) {
alert("Successfully retrieved " + results.length + " scores.");
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
alert(object.id + ' - ' + object.get('playerName'));
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
}

mentioned in a comment above, but I just wanted to end this topic correctly. The two date objects were of different types, so i added .toISOString to the startDate object and it worked like a charm

Related

Protractor not able to execute else part of my code when element is not displayed/present

I always identify element on my screen with isDisplayed/isPresent and then add if/else to perform further test. But else part of the screen never get executed and get error like "Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .noga-selected-summary.list.ng-scope.layout-row)" on console log.
Test_PO.js is as follow,
var ProfilePO = function(){
this.Setting = element.all(by.css('.md-icon-button.md-button.md-dark-theme.md-ink-ripple')).get(1);
this.SettingSubMenus = element.all(by.css('.md-tab.ng-scope.ng-isolate-scope.md-ink-ripple'));
//this.ReqProductLabel = element(by.css('[ng-show="ngModel && ngModel.length > 0"]'));
this.BusinessPage = element(by.css('[ng-model="required_categories"]'));
this.AddProductButton = element(by.css('[ng-click="addCategory()"]'));
this.AddedProdCat = element.all(by.css('.noga-selected-summary.list.ng-scope.layout-row'));
this.DeleteAddedProd = element.all(by.css('[ng-click="removeCategory(category)"]'));};
module.exports = ProfilePO;
test_spec.js is as follow,
it('Verify user can add required products on business screen using Find Product or Service Dropdown', function() {
Profile.AddedProdCat.get(0).isDisplayed().then(function(AddedProdCatIsDisplayed){
console.log('Added Prod Cat Is Displayed: ' + AddedProdCatIsDisplayed);
if (AddedProdCatIsDisplayed) {
Profile.AddedProdCat.count().then(function(count){
var Count1 = count;
var C1 = Count1-1;
console.log('Product list has ' + count + ' products');
for (var i=0, j=0; i <= C1 ; i++) {
Profile.DeleteAddedProd.get(j).click();
console.log('deleted ' + (i+1) + ' product');
browser.sleep(2000);
}
});
} else {
FuncLib.NogaList.isDisplayed().then(function(NogaListIsDisplayed) {
console.log('Find Product or Service Dropdown Is Displayed: ' + NogaListIsDisplayed);
if (NogaListIsDisplayed) {
FuncLib.SltNogaCat("A011100"); //select Noga
Profile.AddProductButton.isDisplayed().then(function (AddProdButtonDisplayed){
console.log('Add product button is displayed: ' + AddProdButtonDisplayed);
Profile.AddProductButton.click();
browser.sleep(3000);
Profile.AddedProdCat.isDisplayed().then(function(AddedProdCatIsDisplayed){
console.log('Added Prod Cat Is Displayed: ' + AddedProdCatIsDisplayed);
expect(Profile.AddedProdCat.getText()).toEqual('A011100');
});
});
} else
console.log('Noga Catagory dropdown is not displayed');
});
}
});
});
When"added product category list" is available on screen, this script works nicely but if I don't have added product category list, it returns above mentioned error. I tried using isPresent instead of isDisplayed but still I get same error. Kindly tell me what I need to do to handle this error?
What version of protractor you are using? This should be fixed starting from 3.3.0 - https://github.com/angular/protractor/commit/bd78dfc79b1435d124c994482df6879066079a4d
I think your this.AddedProdCat takes some time to get displayed.
You can use just wait using Expected Conditions for that element, something like this -
it('Verify user can add required products on business screen using Find Product or Service Dropdown', function() {
var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(Profile.AddedProdCat.get(0)), 5000);
Profile.AddedProdCat.get(0).then(function(firstElement){
console.log('Added Prod Cat firstElement: ' + firstElement);
if (firstElement) {
Profile.AddedProdCat.count().then(function(count){
var Count1 = count;
var C1 = Count1-1;
console.log('Product list has ' + count + ' products');
for (var i=0, j=0; i <= C1 ; i++) {
Profile.DeleteAddedProd.get(j).click();
console.log('deleted ' + (i+1) + ' product');
browser.sleep(2000);
}
});
}
});

Google maps downloadUrl does not return 200

My code is based on the example of google code:
https://developers.google.com/maps/articles/phpsqlinfo_v3
and was working fine.
I need to change a former 'gid' (Integer) field to 'id' (String) to get saved to the database and used to display a new labeled symbol on the map.
The strange thing is, that the url, that is build in the code to call the addrow.php file is OK. When I capture this string with alert(url), and I manually use this string, the new data is added to the database.
In my script, the call seems to fail (responseCode == 200 && data.length <=1), since no data is written to the database and the alert from the 'else-clause' is displayed as short pop-up.
Here's the code I use in my project (to save data from a form):
//save new marker to Postgis-database and add new markerwithlabel on the fly
function saveData(){
var gender = escape(document.getElementById("gender").value);
var hoehe = InZahl(document.getElementById("hoehe").value);
var breite = InZahl(document.getElementById("breite").value);
var id = escape(document.getElementById("id").value);
var vital = document.getElementById("vital").value;
var typ = document.getElementById("typ").value;
var ein_mehr = document.getElementById("ein_mehr").value;
var st_durchm = document.getElementById("st_durchm").value;
var frucht = document.getElementById("frucht").value;
var anmerk = document.getElementById("anmerk").value;
var latlng = marker.getPosition();
var url = "./mapdata/addrow.php?gender=" + gender +
"&hoehe=" + hoehe + "&lat=" + latlng.lat() + "&lng=" + latlng.lng() +
"&breite=" + breite + "&id=" + id + "&typ=" + typ + "&ein_mehr=" +ein_mehr + "&st_durchm=" + st_durchm +
"&frucht=" + frucht +
"&vital=" + vital + "&anmerk=" + anmerk;
downloadUrl(url, function (data, responseCode) {
if (responseCode == 200 && data.length <=1) {
infowindow.close();
marker.setDraggable(false);
marker.setIcon('./images/mm_purple.png');
marker.labelContent = id;
marker.setMap(map);
downloadUrl("./mapdata/getxml_get_last.php", function (data1) {
var xml = parseXml(data1);
var ms = xml.documentElement.getElementsByTagName("m");
var gid = ms[0].getAttribute("gid");
var html_n = "<div id='InfoWindow'><p style='font-weight:bold;'>" + id + "</p> \n\<p>Höhe:" + hoehe + " Breite: "+ breite +
"<br />\n\Typ: "+typ+" Stämme: "+ein_mehr+" St-Durchm: "+ st_durchm + "<br />\n\Vitalität: "+vital+" Fruchtbehang: "+frucht+
"<p/>\n\<p style='text-align:right;'><a href='sm_juniperus.php?operation=ssearch&ResetFilter=0&SearchField=gid&FilterType=%3D&FilterText="+ gid +
"' target='_blank'> Daten editieren </a></p></div>";
infowindow.setContent(html_n);
bindInfoWindow(marker, map, infowindow, html_n);
(function(i, marker, gid) {
var origIcon = marker.getIcon();
new LongPress(marker, 1000);
google.maps.event.addListener(marker, 'longpress', function(e) {
marker.setDraggable(true);
marker.setIcon(mmcross);
});
google.maps.event.addListener(marker, 'dragend', function(){
updatePosition(marker, gid);
marker.setIcon(origIcon);
});
})(i,marker,gid);
//add new marker to markerCluster-Array and to markerArray
markerCluster.addMarker(marker,false);
markerArray.push(marker);
i++;
}); // End add new marker
}
else {
alert("Your data couldn't be saved!");
}
}); // End downloadUrl
}; // END saveData()
As I said, my code worked fine, but after 3 evenings passed to solve this, I thought it would be time to ask for help.
If anybody has an idea, where the mistake lies, I would apreciate any hint.
Just to confirm, you're aware that you by doing
if (responseCode == 200 && data.length <=1) {
you are saying 'if the request is successful and the data it returns is only one character or below in length'? I am unsure if this is intended or not, because this way the code inside the if statement is only ran if the response is successful but contains only 1 or 0 characters.

Google Apps Script: How to pull values from column A based on values in column E and send all values in one email?

I'm trying to create a script for a student attendance spreadsheet that will look in Column E for the string "X". For each instance of "X", the string from column A (the student name) will be added to the body of an email. I'm pretty new to JavaScript, although I have been studying the basics. I've done a lot of research and found some scripts I was able to modify to send an individual email for each instance of X in E. However, I have not been able to figure out how to combine that information into a single email.
Here's what I have so far:
function Email_ReminderNS() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("July_August"),
EMAIL_SENT = "EMAIL_SENT",
statusArray = sheet.getDataRange().getValues();
var class = statusArray[0][8],
status = "X",
email = "XXXX"
for (i=7;i < statusArray.length;i++){
var emailSent = statusArray[i][84];
if (status == statusArray[i][4] & emailSent != EMAIL_SENT) {
var student = statusArray[i][0];
var body = "This is a No-Show Report for " +student+ " from " + class;
var subject = "No-Show Report for " + student+ " from " + class;
MailApp.sendEmail(email,subject,body,{NoReply : true});
sheet.getRange(i+1, 85).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
I realize I'll probably need to move the sendEmail function to be outside the IF statement. I tried to create an array with the names and join those into a string and add it to the body of the email, but I've had no luck. It just ended up sending the last name instead of all of them.
If anyone has any suggestions for me I would be deeply grateful.
First set up variables to keep track of which student did not show up:
var students = [];
var student_rows = [];
Then, add student to these arrays when X is found:
if (status == statusArray[i][4] & emailSent != EMAIL_SENT) {
var student = statusArray[i][0];
students.push(student);
student_rows.push(i+1);
}
Then send the email with all student names combined (outside of the for loop like you said)
var body = "This is a No-Show Report for " + students.join(', ') + " from " + class;
var subject = "No-Show Report for " + students.join(', ') + " from " + class;
MailApp.sendEmail(email,subject,body,{NoReply : true});
Finally update the spreadsheet indicating which names were in that email:
for (var i=0; i<student_rows.length; i++) {
sheet.getRange(student_rows[i], 85).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
Here's the complete script:
function Email_ReminderNS() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("July_August"),
EMAIL_SENT = "EMAIL_SENT",
statusArray = sheet.getDataRange().getValues();
var class = statusArray[0][8],
status = "X",
email = "francis#bposolutions.com";
var students = [];
var student_rows = [];
for (i=7;i < statusArray.length;i++){
var emailSent = statusArray[i][84];
if (status == statusArray[i][4] & emailSent != EMAIL_SENT) {
var student = statusArray[i][0];
students.push(student);
student_rows.push(i+1);
}
}
var body = "This is a No-Show Report for " + students.join(', ') + " from " + class;
var subject = "No-Show Report for " + students.join(', ') + " from " + class;
MailApp.sendEmail(email,subject,body,{NoReply : true});
for (var i=0; i<student_rows.length; i++) {
sheet.getRange(student_rows[i], 85).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
There are probably many ways to implement a new version of your code, the other answer probably works but I think it can be improved (a bit).
First of all, you can get rid of the flush method that does nothing else than slowing down the function (it was originally used in the Google example to check the sent status row by row, it is useless when we send only one mail with all the data in it)
Secondly, it might be a good idea to use html format to get a better looking result.
And lastly, it is good practice to write back to the sheet using one setValues instead of multiple setValue() in a loop.
Here is a possible replacement code, you'll have to "tune" it to your needs to eventually improve the message format but the main structure is there and working.
function Email_ReminderNS() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("July_August"),
statusArray = sheet.getDataRange().getValues();
var email = Session.getActiveUser().getEmail(); //replace with the email you want, this value will send mails to you I used it for test.
var class = statusArray[0][8],
status = "X",
students = [];
for (var i=7;i < statusArray.length; i++){
var emailSent = statusArray[i][84];
if (status == statusArray[i][4] & emailSent != "EMAIL_SENT") {
students.push(statusArray[i][0]);
statusArray[i][84]="EMAIL_SENT";
}
}
var subject = "No-Show Report for " + students.length + " from " + class;
var textBody = "This is a No-Show Report for " +students.length+ " from " + class+"\n";
var HTMLBody = "<b>This is a No-Show Report for " +students.length+ " from " + class+"</b><br><br>"
+'<table style="background-color:lightblue;border-collapse:collapse;" border = 1 cellpadding = 5><th>Sent Mails</th><tr>';
for(var n in students){
HTMLBody += '<tr><td>'+n+'</td><td>'+statusArray[n][0]+'</td></tr>';
textBody += '\n'+n+' - '+statusArray[n][0];
}
HTMLBody+='</table><BR> kind regards.' ;
textBody+='\n\nKind regards';
Logger.log(HTMLBody);
Logger.log(textBody);
MailApp.sendEmail(email,subject,textBody,{'NoReply' : true, 'htmlBody' : HTMLBody});
sheet.getRange(1,1,statusArray.length,statusArray[0].length).setValues(statusArray);
}

Mongo dbref additional fields are invisible in mongoshell. How to display them?

Background: This problem came up with Doctrine ODM, that uses a _doctrine_class_name field in DBRefs that is invisible in the Mongo shell (2.2.2) and caused quite a culprit, when we had to update a record manually.
Example:
mongoshell> use testdb; // for safety
mongoshell> a = DBRef("layout_block", ObjectId("510a71fde1dc610965000005")); // create a dbref
mongoshell> a.hiddenfield = "whatever" // add a field that's normally not there like Doctrine does
mongoshell> a // view it's contents, you won't see hiddenfield
mongoshell> for (k in a) { var val = a[k]; print( k + "(" + typeof(val) + "): " + val ); } // you can see that there's more if you iterate through it
mongoshell> db.testcoll.save({ref: [ a ]}) // you can have it in a collection
mongoshell> db.testcoll.findOne(); // and normally you won't see it
Without an iteration like the third command from below (or MongoVue), you won't ever know there's more in a DBRef if you simply use find(). I have not found any usable modifier for find()(tried: toArray, tojson, printjson, toString, hex, base64, pretty, chatty, verbose, ...).
Has anybody got a method to display DBRef contents verbosely in mongo shell?
The Mongo shell is an extension of Mozilla SpiderMonkey (1.7?) and has pretty bare bones functionality.
The suggestion from a MongoDB blog post on the shell is to define the following inspect function in .mongorc.js in your home directory
function inspect(o, i) {
if (typeof i == "undefined") {
i = "";
}
if (i.length > 50) {
return "[MAX ITERATIONS]";
}
var r = [];
for (var p in o) {
var t = typeof o[p];
r.push(i + "\"" + p + "\" (" + t + ") => " +
(t == "object" ? "object:" + inspect(o[p], i + " ") : o[p] + ""));
}
return r.join(i + "\n");
}
Additionally you can redefine the DBRef.toString function as something like:
DBRef.prototype.toString = function () {
var r = ['"$ref": ' + tojson(this.$ref), '"$id": ' + tojson(this.$id)];
var o = this;
for (var p in o) {
if (p !== '$ref' && p !== '$id') {
var t = typeof o[p];
r.push('"' + p + '" (' + t + ') : ' +
(t == 'object' ? 'object: {...}' : o[p] + ''));
}
}
return 'DBRef(' + r.join(', ') + ')';
};

YUI 3 Autocomplete Textbox Value Change

The question I have is how I would be able to change the value that is set in the text box that the autocomplete is linked to. The task I am attempting to do is to convert from YUI 2 to YUI 3. Please don't say that I shouldn't do that... because It isn't my choice. I am aware... The code below is what was used before. I already have the autocomplete functionality doing most of what it needs to do. It's just when it gets to the field.itemSelectEvent.subscribe(myHandler) part that I can no longer get anything else to work. The list comes up with the persons information but when selected it just puts [object Object] in the text box instead of their name that automatically forwards to another page. Thank you for your help!!!
var field = new YAHOO.widget.AutoComplete("webUserSearch",
"webUserSearchContainer", oDS);
field.highlightClassName = "autoCompleteHighlight";
field.useShadow = true;
field.queryMatchContains = true;
field.maxResultsDisplayed = 20;
field.resultTypeList = false;
field.formatResult = function(oResultData, sQuery) {
return "<div class=\"result\"><u style=\"cursor:pointer\">"
+ oResultData['Last Name'] + ", " + oResultData['First Name']
+ "</u> (" + oResultData['User Name'] + ")</div>";
};
var myHandler = function(sType, aArgs) {
var theField = aArgs[0];
var selectedElement = aArgs[1];
var repObject = aArgs[2];
theField.getInputEl().value = repObject['Last Name'] + ", "
+ repObject['First Name'];
var newTabURL = <URL Removed for Stack Overflow>;
window.location.href = newTabURL;
};
field.itemSelectEvent.subscribe(myHandler);
Listen for the select event, then in the handler for that you'll get a result object. The structure of that is described in the docs for the result event (a little up from the select event).
I usually take a value out of the raw property on the result object to stick into the field.
resultTextLocator was the ticket. All I had to do was to return the value I wanted to display in the box.
resultTextLocator : function (result) {
return result["Last Name"] +
', ' +
result["First Name"];
}