How do I resolve code.org's App Lab readRecord() asynchronous timing? - code.org

I'm a fairly new student in AP CSP, and I wanted to create a username/password system in code.org's App Lab, however, it requires me to get the readRecords() command to function first.
I have the code as such :
function read (array) {
var truth;
readRecords("loginarray", {}, function(records) {
if (records.length > 0) {
for (var i = 0; i < records.length; i++){
if (array.user == records[i].user){
if (array.pass == records[i].pass) {
truth = false;
hideElement("unverifiedtext");
hideElement("retrybutton");
setScreen("verifyscreen");
}
}
}
}
}
);
return truth;
}
But nothing I do seems to get the readRecords() command working. I'm rather confused, can this asynchronous timing be meddled with at all? If not, how should I go about fixing this issue?
Thanks in advance!

Related

Break on ForEach() dart

I'm writing a function where I iterate thru a map and look test for valid values on an function. My question is there is a better way to correctly break from a foreach loop when an error is found?
('break' does not work on foreach())
Since I am not able to use the break function here so i had to place a bool marker :/
Any help in making this code nice looking would be appreciated :)
Future<bool> saveToKeychainFunc(Map data) {
bool saved = false;
bool error = false;
data?.keys?.forEach((item) async {
if (data[item] != null) {
await _storage.write(key: item.toString(), value: data[item].toString());
} else {
//TODO
// data error, we got null for a value!
error = true;
}
saved = true;
});
return (error == true) ? false : saved;
}
I've experienced this. My work around is using for loop instead.
ex:
for (int i = 0; i < jsonTransactions.length; i++) {
Transaction transaction = Transaction.fromJson(jsonTransactions[i]);
transactions.add(transaction);
}
You can just add conditions, and add your break inside the loop if conditions are met. Since you're using a map, my code should not be very different since Map also has .length

Google form that turns on and off each day automatically

I love Google Forms I can play with them for hours. I have spent days trying to solve this one, searching for an answer. It is very much over my head. I have seen similar questions but none that seemed to have helped me get to an answer. We have a café where I work and I created a pre-order form on Google Forms. That was the easy part. The Café can only accept pre-orders up to 10:30am. I want the form to open at 7am and close at 10:30am everyday to stop people pre ordering when the café isn't able to deal with their order. I used the very helpful tutorial from http://labnol.org/?p=20707 to start me off I have added and messed it up and managed to get back to the below which is currently how it looks. It doesn't work and I can't get my head around it. At one point I managed to turn it off but I couldn't turn it back on!! I'm finding it very frustrating and any help in solving this would be amazing. To me it seems very simple as it just needs to turn on and off at a certain time every day. I don't know! Please help me someone?
FORM_OPEN_DATE = "7:00";
FORM_CLOSE_DATE = "10:30";
RESPONSE_COUNT = "";
/* Initialize the form, setup time based triggers */
function Initialize() {
deleteTriggers_();
if ((FORM_OPEN_DATE !== "7:00") &&
((new Date()).getTime("7:00") < parseDate_(FORM_OPEN_DATE).getTime ("7:00"))) {
closeForm("10:30");
ScriptApp.newTrigger("openForm")
.timeBased("7:00")
.at(parseDate_(FORM_OPEN_DATE))
.create(); }
if (FORM_CLOSE_DATE !== "10:30") {
ScriptApp.newTrigger("closeForm")
.timeBased("10:30")
.at(parseDate_(FORM_CLOSE_DATE))
.create(); }
if (RESPONSE_COUNT !== "") {
ScriptApp.newTrigger("checkLimit")
.forForm(FormApp.getActiveForm())
.onFormSubmit()
.create(); } }
/* Delete all existing Script Triggers */
function deleteTriggers_() {
var triggers = ScriptApp.getProjectTriggers();
for (var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
}
/* Allow Google Form to Accept Responses */
function openForm() {
var form = FormApp.getActiveForm();
form.setAcceptingResponses(true);
informUser_("Your Google Form is now accepting responses");
}
/* Close the Google Form, Stop Accepting Reponses */
function closeForm() {
var form = FormApp.getActiveForm();
form.setAcceptingResponses(false);
deleteTriggers_();
informUser_("Your Google Form is no longer accepting responses");
}
/* If Total # of Form Responses >= Limit, Close Form */
function checkLimit() {
if (FormApp.getActiveForm().getResponses().length >= RESPONSE_COUNT ) {
closeForm();
}
}
/* Parse the Date for creating Time-Based Triggers */
function parseDate_(d) {
return new Date(d.substr(0,4), d.substr(5,2)-1,
d.substr(8,2), d.substr(11,2), d.substr(14,2));
}
I don't think you can use .timebased('7:00'); And it is good to check that you don't have a trigger before you try creating a new one so I like to do this. You can only specify that you want a trigger at a certain hour like say 7. The trigger will be randomly selected somewhere between 7 and 8. So you really can't pick 10:30 either. It has to be either 10 or 11. If you want more precision you may have to trigger your daily triggers early and then count some 5 minute triggers to get you closer to the mark. You'll have to wait to see where the daily triggers are placed in the hour first. Once they're set they don't change.
I've actually played around with the daily timers in a log by creating new ones until I get one that close enough to my desired time and then I turn the others off and keep that one. You have to be patient. As long as you id the trigger by the function name in the log you can change the function and keep the timer going.
Oh and I generally created the log file with drive notepad and then open it up whenever I want to view the log.
function formsOnOff()
{
if(!isTrigger('openForm'))
{
ScriptApp.newTrigger('openForm').timeBased().atHour(7).create()
}
if(!isTrigger('closeForm'))
{
ScriptApp.newTrigger('closeForm').timeBased().atHour(11)
}
}
function isTrigger(funcName)
{
var r=false;
if(funcName)
{
var allTriggers=ScriptApp.getProjectTriggers();
var allHandlers=[];
for(var i=0;i<allTriggers.length;i++)
{
allHandlers.push(allTriggers[i].getHandlerFunction());
}
if(allHandlers.indexOf(funcName)>-1)
{
r=true;
}
}
return r;
}
I sometimes run a log entry on my timers so that I can figure out exactly when they're happening.
function logEntry(entry,file)
{
var file = (typeof(file) != 'undefined')?file:'eventlog.txt';
var entry = (typeof(entry) != 'undefined')?entry:'No entry string provided.';
if(entry)
{
var ts = Utilities.formatDate(new Date(), "GMT-6", "yyyy-MM-dd' 'hh:mm:ss a");
var s = ts + ' - ' + entry + '\n';
myUtilities.saveFile(s, file, true);//this is part of a library that I created. But any save file function will do as long as your appending.
}
}
This is my utilities save file function. You have to provide defaultfilename and datafolderid.
function saveFile(datstr,filename,append)
{
var append = (typeof(append) !== 'undefined')? append : false;
var filename = (typeof(filename) !== 'undefined')? filename : DefaultFileName;
var datstr = (typeof(datstr) !== 'undefined')? datstr : '';
var folderID = (typeof(folderID) !== 'undefined')? folderID : DataFolderID;
var fldr = DriveApp.getFolderById(folderID);
var file = fldr.getFilesByName(filename);
var targetFound = false;
while(file.hasNext())
{
var fi = file.next();
var target = fi.getName();
if(target == filename)
{
if(append)
{
datstr = fi.getBlob().getDataAsString() + datstr;
}
targetFound = true;
fi.setContent(datstr);
}
}
if(!targetFound)
{
var create = fldr.createFile(filename, datstr);
if(create)
{
targetFound = true;
}
}
return targetFound;
}

What is the most efficient way to call another function in parent function to execute Palindrome function?

In programming, there are multiple ways of doing the same problem. The following problem is in regards to palindrome. Though I feel that I am on the right track, I am not able to completely solve the problem to get to requested solution.
What is a palindrome? A word written forward or backward is the same and returns true. Example, "racecar". Hence, I designed the following code in Javascript...
function palindrome(string) {
string = string.toLowerCase();
lowString = string.toLowerCase().split("").reverse().join("");
for (var i=0; i<string.length; i++) {
if (string[i] !== lowString[i]) {
return false;
}
}
}
return true;
}
The above code returns true if Palindrome exists and returns false if not.
Then, the problem says - Given various palindrome in a string or array, please return the longest palindrome. So, I wrote the following:
function longestPalindrome(newstring) {
splitString = newString.split(" ");
for (var i=0; i < splitString; i++) {
if (splitString[i] == palindrome(splitString[i]) {
console.log(splitString[i]);
}
}
}
longestPalindrome("This is a racecar ada");'
But in the above code, I am not able to get the required outcome because I believe I am not calling the function correctly.
I would appreciate clear directions or even a solution built off of my track as well as the track you deem fittest.

bing maps upgrading from v7 to v8 error with userMapView

I'm upgrading a project from using the bing maps v7 ajax api to using the v8 api. I've run into a problem where I'm getting back a message saying that "The waypoint you entered cannot be found." So I backed up and modified a sample screen to do what I'm doing and it works fine. So I've narrowed it down (with fiddler) to the REST calls that are made for each waypoint getting an error saying the userMapView is out of range in the first case but works fine in the second. I'm not really sure why this might be different in the sample code versus my actual app. Here are the two URLs. The first is the one that fails:
https://dev.virtualearth.net/REST/v1/Locations/?q=Cincinnati%2C%20OH&o=json&culture=en-US&jsonp=Microsoft.Maps.NetworkCallbacks.f5de44&key=MY_BING_MAPS_KEY&maxResults=5&userMapView=39.18820190429691,-180,39.18820190429691,-180&inclnb=0&incl=
https://dev.virtualearth.net/REST/v1/Locations/?q=cincinnati%2C%20oh&o=json&culture=en-US&jsonp=Microsoft.Maps.NetworkCallbacks.f66617&key=MY_BING_MAPS_KEY&maxResults=5&userMapView=39.02836016935031,-85.12275695800781,39.34768093312603,-85.12275695800781&inclnb=0&incl=
If I replace the userMapView parameter of the first URL with those of the second, the first URL works too. It seems obvious that the "-180" degree part is incorrect, but I don't know how it is getting there.
BTW, both of these URLs were generated using my dev key.
Thanks for any help!
EDIT:
Here's the bulk of the code that runs into trouble. Prior to this I've new'd the Map. This code is the callback from the loadModule of the Directions module. The code is a little convoluted beyond that though as I'm plugging in origins and destinations from the form. Also note, not that it makes much difference, that userAddress is passed into this function as true.
function createDrivingRoute(useAddress) {
directionsManager = new Microsoft.Maps.Directions.DirectionsManager(bmap);
locs = [];
var fromWayPoint;
fromWayPoint = new Microsoft.Maps.Directions.Waypoint({ address: fromAddressSearch });
locs.push(fromWayPoint);
directionsManager.addWaypoint(fromWayPoint);
if (toLocationArray != null) {
if (toLocationArray.length == 1) {
if (toLocationArray[0] == false) {
toLocationArray = [];
}
}
}
if (useAddress) {
if (toLocationArray != null) {
for (i = 0; i < toLocationArray.length; i++) {
//var toWayPointLoc = new Microsoft.Maps.Directions.Waypoint({ location: toLocationArray[i] });
var toWayPointLoc = new Microsoft.Maps.Directions.Waypoint({ address: toLocationArray[i] });
locs.push(toWayPointLoc);
directionsManager.addWaypoint(toWayPointLoc);
}
for (i = 0; i < toAddressArray.length; i++) {
var toWayPoint = new Microsoft.Maps.Directions.Waypoint({ address: toAddressArray[i] });
locs.push(toWayPoint);
directionsManager.addWaypoint(toWayPoint);
}
} else {
for (i = 0; i < toAddressArray.length; i++) {
var toWayPoint = new Microsoft.Maps.Directions.Waypoint({ address: toAddressArray[i] });
locs.push(toWayPoint);
directionsManager.addWaypoint(toWayPoint);
}
}
} else {
if (toLocationArray != null) {
for (i = 0; i < toLocationArray.length; i++) {
//var toWayPointLoc = new Microsoft.Maps.Directions.Waypoint({ location: toLocationArray[i] });
var toWayPointLoc = new Microsoft.Maps.Directions.Waypoint({ address: toLocationArray[i] });
locs.push(toWayPointLoc);
directionsManager.addWaypoint(toWayPointLoc);
}
}
for (i = 0; i < toAddressArray.length; i++) {
var toWayPoint = new Microsoft.Maps.Directions.Waypoint({ address: toAddressArray[i] });
locs.push(toWayPoint);
directionsManager.addWaypoint(toWayPoint);
}
}
if ($get("<%= chkReturnOrigin.ClientID %>").checked) {
var returnWayPoint = new Microsoft.Maps.Directions.Waypoint({ address: fromAddressSearch });
directionsManager.addWaypoint(fromWayPoint);
}
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: '#directions' });
// Specify a handler for when the directions are calculated
if (directionsUpdatedEventObj) {
Microsoft.Maps.Events.removeHandler(directionsUpdatedEventObj);
directionsUpdatedEventObj = null;
}
directionsUpdatedEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', onDirectionsDisplayedEvent);
if (directionsErrorEventObj) {
Microsoft.Maps.Events.removeHandler(directionsErrorEventObj);
directionsErrorEventObj = null;
}
directionsErrorEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsError', onDirectionsErrorEvent);
loadedRoute = null;
loadedSteps = [];
directionsManager.calculateDirections();
var destAddress = $get("<%= DestAddressList.ClientID %>").value;
if (destAddress == null || destAddress == "") {
document.getElementById("DistTotal").innerHTML = '';
}
}
Haven't seen this issue before, very odd. Take a look at your code, if you are using the Search module to do the geocoding, don't set the bounds option and see if it that corrects the issue. The bounds property is used to set the userMapView property of the REST request. If that works, then there is likely an issue with the LocationRect object being passed in, or how the search module uses it. I'll take a look into the source code to see if there is a bug that might be causing this.
Update 1: Now that I see your edit and see that you are using the directions manager I'm able to see that the userMapView is automatically added from the map. Not sure why it would be adding such incorrect values though. It looks like they are adding the same coordinate twice rather than adding the northwest and southeast coordinates. Will see if I can verify this by digging through the code.
Update 2: I've found the bug in the code. I have logged this with the development team so that they can resolve it the next time they touch the code for the search manager. The issue is that the west value is being added to the userMapView request twice, but not adding east value.
Update 3: Good news, this bug is now resolved in the experimental branch of Bing Maps. You can try this out by adding "&branch=experimental" to the map script URL. This will be added to the release branch in the next regular update planned for February.

Project Browser not updating with Package Deletion Script

The following method deletes a package. The problem is that the Project Browser is never refreshed. Calling Repository.RefreshModelView(0) forces the update, but it reopens the model and kills script execution.
Here is the method:
function clearPackage( pkg ) {
var parent as EA.Package;
parent = Repository.GetPackageByID(pkg.ParentID);
var pkgList as EA.Collection;
pkgList = parent.Packages;
for (var i = 0; i < pkgList.Count; i++) {
var p as EA.Package;
p = pkgList.GetAt(i);
if (p.PackageGUID == pkg.PackageGUID) {
pkgList.Delete(i);
pkgList.Refresh();
parent.Update(); // have tried with and without
return;
}
}
}
Inspecting pkgList.Count before and after pkgList.Refresh does show a change in size. Again, the problem seems limited to the Project Browser.
Any ideas on how to refresh the Project Browser?
Cross posted on Sparx Forums.
To delete a package you just need to delete the package itself. Sorry for the Perl, but thats my donkey :-)
my $p = $rep->GetTreeSelectedObject();
my $par = $rep->GetPackageByID ($p->ParentID);
my $idx = 0;
for my $sp (in $par->Packages) {
if ($sp->PackageID == $p->PackageID) {
$par->Packages->DeleteAt ($idx, 1);
last;
}
$idx++;
}
$rep->RefreshModelView ($par->PackageID);
Try
Repository.RefreshModelView(parent.PackageID);
That will refresh only the contents of the parent package, not the whole model.