# readRecords issue

**URL:** <https://forum.code.org/t/readrecords-issue/32827>\
**Category:** Website and Tools Questions\
**Created:** [June 30, 2020, 4:10pm UTC](https://forum.code.org/t/readrecords-issue/32827 "2020-06-30T16:10:14Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![carol.ramsey](https://avatars.discourse-cdn.com/v4/letter/c/ac8455/32.png) [@carol.ramsey](https://forum.code.org/u/carol.ramsey)\
**Post date:** [June 30, 2020, 4:10pm UTC](https://forum.code.org/t/readrecords-issue/32827/1 "2020-06-30T16:10:14Z")

</div>

my project - [https://studio.code.org/projects/applab/xEEOqp8zpOJ2g-YyCntajlhvh0crb2ysLvP1Pg5LCF8](https://studio.code.org/projects/applab/xEEOqp8zpOJ2g-YyCntajlhvh0crb2ysLvP1Pg5LCF8)

Hi! Thanks for reading!

The readRecords on line 71 isn’t doing anything. In the debugger, it passes by it, with numStudents staying at 0, even though there are records in the data table. This happens when I limit the records being asked for, and when asking for all of them.

If you have another minute - is there a more elegant way to represent table data in memory? AppLab doesn’t have two-dimensional arrays or structures, that I can tell. The examples I find all use the table data right away, without storing it outside of readRecords.

Carol

---

<div class="post-metadata">

**Author:** ![infinitestasis](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/infinitestasis/32/5047_2.png) [@infinitestasis](https://forum.code.org/u/infinitestasis)\
**Post date:** [July 1, 2020, 11:18am UTC](https://forum.code.org/t/readrecords-issue/32827/2 "2020-07-01T11:18:22Z")

</div>

Unfortunately readRecords, createRecord, or any other data manipulating function is asynchronous. That is why a callback must be supplied. On line 91 and 92, it appears like the code expected readRecords to either be instant or suspend execution until the callback was called. A simple fix would be making currentNameIndex=-1 and learnNextName() a part of the callback.

Since numStudents does work after the fix, it seems the problem is solved. However the text does not display anything so there appear to be other problems. Since I am unsure of what the expectations are and what actually happens, I can’t really help with that.

As for the other ways to store data, I don’t have much experience with createRecord but I suppose it is possible to stringify json and then parse it afterwards.

---

<div class="post-metadata">

**Author:** ![carol.ramsey](https://avatars.discourse-cdn.com/v4/letter/c/ac8455/32.png) [@carol.ramsey](https://forum.code.org/u/carol.ramsey)\
**Post date:** [July 1, 2020, 2:50pm UTC](https://forum.code.org/t/readrecords-issue/32827/3 "2020-07-01T14:50:52Z")

</div>

Thank you for your time!

I made the change, but the behavior is the same. I still get numStudents = 0. Did I misunderstand your fix? (Lines 71-93)

Carol

---

<div class="post-metadata">

**Author:** ![jdonwells](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/jdonwells/32/7900_2.png) [@jdonwells](https://forum.code.org/u/jdonwells)\
**Post date:** [July 2, 2020, 7:12pm UTC](https://forum.code.org/t/readrecords-issue/32827/4 "2020-07-02T19:12:01Z")

</div>

Mostly this works now. I uncommented all the code that you took out to debug. I also removed event as a parameter to get rid of all those yellow triangles. While it is true they are just warnings, it is also true they are sometimes useful and best to remove them all.

I moved the 4 text labels around so it doesn’t overlap the 4 radio buttons. Testing shows it can put things into the database. That’s good.

You have a bit of an initialization problem. One programming proverb I like is: Once and only once. People forget the first part a lot, the once part. So let’s include something you didn’t say and create a function.

```javascript
function learnNames () {
  currentNameIndex = -1;
  score = 0;
  tries = 0;
  learnNextName();
}

```

This function says that the first name is different than the following name. And it is because we need to do some initialization. So we call this function to start the guessing game instead of `learnNextName`.

Let’s look at the guessing game portion.

```javascript
else {  
          randomIndex = i;
          while (randomIndex === i)
            randomIndex = randomNumber(0, numStudents-1);
          setText (nameLabels[i], goesBys[randomIndex]+ " " +lasts[randomIndex].substring(0,1)+"."); 
        }

```

There are some problems here. First off if there is only one student in the database you have an infinite loop. The second thing I see is you expect there to be 4 and only 4 students. I think maybe you meant to have `randomIndex = currentNameIndex`. So we can try that.

Next we see ` if((correctNameIndex == 1) && (getChecked (nameRadios[correctNameIndex]))) {` That first clause is only going to work 25% of the time so lets take that out.

Let’s also get rid of a couple lines and create a function with the duplicated code:

```javascript

function shortName(n) {
  return goesBys[n]+ " " +lasts[n].substring(0,1)+".";
}

```

Now we see an error. `setText(nameLabels[i], shortName(i));` When we substitute the function we see that `i` is not the correct index and we change it to `setText(nameLabels[i], shortName(currentNameIndex));` And that seems good, but…

Now we have an out of bounds problem. Looking at the code we see: ` if (currentNameIndex == numStudents)`. That is a problem because `currentNameIndex` starts at 0. I know that you know this because you accounted for that elsewhere in the program. So change that to `if (currentNameIndex === numStudents - 1)`

I think you have a naming problem. You have `correctNameIndex`, `currentNameIndex`, and `randomIndex`. If you change these to `correctRadioButton`, `currentStudent`, and `randomRadioButton` you wouldn’t have the same kind of confusion.

I think that is enough for you to chew on for now. Let us know how it is going.

---

<div class="post-metadata">

**Author:** ![carol.ramsey](https://avatars.discourse-cdn.com/v4/letter/c/ac8455/32.png) [@carol.ramsey](https://forum.code.org/u/carol.ramsey)\
**Post date:** [July 4, 2020, 8:11pm UTC](https://forum.code.org/t/readrecords-issue/32827/5 "2020-07-04T20:11:08Z")

</div>

Don,

Thanks for all the info! This is awesome! I made a lot of changes based on your feedback.

There is something basic wrong with the code before learnNames, in the onEvent for choosePeriodNext (line 71), with readRecords.

Is the debugger supposed to work within readRecords, or does the callBack functionality not work with the debugger? (I can’t step through this code.)

When I break immediately after readRecords (line 89), numStudents == 0 and there is no content in the arrays. The data table exists, with 12 records. A much earlier version of the code was able to read the table and the console.log statement printed the names.

Am I using readRecords properly? Is there a timing issue with the callBack?

Thank you. I appreciate your time very much!

Carol

---

<div class="post-metadata">

**Author:** ![jdonwells](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/jdonwells/32/7900_2.png) [@jdonwells](https://forum.code.org/u/jdonwells)\
**Post date:** [July 4, 2020, 8:15pm UTC](https://forum.code.org/t/readrecords-issue/32827/6 "2020-07-04T20:15:48Z")

</div>

You can set a breakpoint in the callback function. When and if it is called it will break. Callbacks are never guaranteed to run. In the case of database calls, if access to the database is somehow blocked it will never run.

When I got your code to run I had to make the code where you fill the arrays with data not commented out. Is that your problem? Sometimes it is the simple stuff.

---

<div class="post-metadata">

**Author:** ![jdonwells](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/jdonwells/32/7900_2.png) [@jdonwells](https://forum.code.org/u/jdonwells)\
**Post date:** [July 4, 2020, 8:20pm UTC](https://forum.code.org/t/readrecords-issue/32827/7 "2020-07-04T20:20:14Z")

</div>

You should also be aware of how the select photo widget works. You select a photo and press open. What happens is that photo is transferred to the [studio.code.org](http://studio.code.org) server and given a random name. That random name is available within the session data for your browser connection. What that means is that when you close your browser be it Chrome, IE, Firefox, or Edge those photos are gone.

---

<div class="post-metadata">

**Author:** ![carol.ramsey](https://avatars.discourse-cdn.com/v4/letter/c/ac8455/32.png) [@carol.ramsey](https://forum.code.org/u/carol.ramsey)\
**Post date:** [July 4, 2020, 8:36pm UTC](https://forum.code.org/t/readrecords-issue/32827/8 "2020-07-04T20:36:57Z")

</div>

Don,

Oh no! I thought I was super lucky when I saw the photo element. I had assumed that security wouldn’t allow a file upload, but then imagined that [Code.org](http://Code.org) found a secure method. When I tested it, I didn’t close my browser. Bummer. I will have to upload the photos manually.

I agree it is something simple with the function that contains readRecords (lines 71-92). The lines in this function aren’t in comments anymore. When I add a break before readRecords, the debugger passes right over it. Do you see anything?

onEvent(“choosePeriodNext”, “click”, function() {  
// var chosenPeriod = getText(“period2”);  
readRecords(“Students”, {}, function(records) {  
numStudents = records.length;  
if (numStudents\>0) {  
for (var i =0; i \< numStudents; i++) {  
console.log (records[i].goesBy);  
goesBys[i] = records[i].goesBy;  
pronounss[i] = records[i].pronouns;  
periods[i] = records[i].period;  
firsts[i] = records[i].first;  
lasts[i] = records[i].last;  
games[i] = records[i].game;  
jobs[i] = records[i].job;  
goodAts[i] = records[i].goodAt;  
toKnows[i] = records[i].toKnow;  
photos[i] = records[i].photo;  
}  
learnNames();  
} else setScreen (“home”);  
});  
});

Here is the project link, if that is easier - [https://studio.code.org/projects/applab/xEEOqp8zpOJ2g-YyCntajlhvh0crb2ysLvP1Pg5LCF8](https://studio.code.org/projects/applab/xEEOqp8zpOJ2g-YyCntajlhvh0crb2ysLvP1Pg5LCF8)

Thank you for your time. I’m new to AppLab and getting good practice!

Carol

---

<div class="post-metadata">

**Author:** ![jdonwells](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/jdonwells/32/7900_2.png) [@jdonwells](https://forum.code.org/u/jdonwells)\
**Post date:** [July 5, 2020, 3:38am UTC](https://forum.code.org/t/readrecords-issue/32827/9 "2020-07-05T03:38:42Z")

</div>

That actually works.

`readRecords` has a function expression for the callback parameter that the debugger will pass over because it isn’t called till later. To break inside that loop you need a breakpoint inside the function.

---

<div class="post-metadata">

**Author:** ![jdonwells](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/jdonwells/32/7900_2.png) [@jdonwells](https://forum.code.org/u/jdonwells)\
**Post date:** [July 5, 2020, 1:51pm UTC](https://forum.code.org/t/readrecords-issue/32827/10 "2020-07-05T13:51:06Z")

</div>

Looking through your code I do have a so called pro-tip for you. Break the code down into smaller pieces. App Lab doesn’t really encourage you to do that. If anything they tend to promote that bad habit. One thing to start with is turning all those function expressions into named functions.

So try something like this:

```javascript
onEvent("choosePeriodNext", "click", getStudentsFromDatabase);

function getStudentsFromDatabase () {
  readRecords("Students", {period: getText("period2")}, recievedStudentsFromDatabase);
}

function recievedStudentsFromDatabase (records) {
  numStudents = records.length;
  if (numStudents > 0) {
    for (var i = 0; i < numStudents; i++) {
      goesBys[i] = records[i].goesBy;
      pronounss[i] = records[i].pronouns;
      periods[i] = records[i].period;
      firsts[i] = records[i].first;
      lasts[i] = records[i].last;
      games[i] = records[i].game;
      jobs[i] = records[i].job;
      goodAts[i] = records[i].goodAt;
      toKnows[i] = records[i].toKnow;
      photos[i] = records[i].photo; 
    }
    learnNames();    
  } else setScreen ("home");
}

```

The blocks tend to push you toward using function expressions, but when you get to a program of this complexity it is time to switch to text and write it out with names that describe what it does.

Now let’s look at those arrays. You don’t need them. I know you know how to use objects because you write statements like `goesBys[i] = records[i].goesBy;` So instead of taking all the values out of the objects just use the objects.

While we are at it change `numStudents` to `numberOfStudents` we started that whole abbreviation thing in the 60s when FORTRAN only let you have 8 letters to name a variable. With auto-complete we don’t do that anymore.

Let’s also create a function to help us understand what is happening. This is called an explaining message. Why not 2?

```javascript
var students; //move this to the top

function noStudents () {
  setScreen ("home");
}

function chosenPeriod () {
  return getText("period2");
}

onEvent("choosePeriodNext", "click", getStudentsFromDatabase);

function getStudentsFromDatabase () {
  readRecords("Students", {period: chosenPeriod()}, receivedStudentsFromDatabase);
}

function receivedStudentsFromDatabase (records) {
  students = records;
  numberOfStudents = students.length;
  if (numberOfStudents > 0) {
    learnNames();    
  } else {
    noStudents();
  }
}

```

One Javascript best practice is to always use a block after if and else. So I wrapped a block around `noStudents();`. App Lab is just an old version of Javascript.

`learnNextName` still has a bug in it try breaking it down into smaller pieces with functions that explain what the code is doing. When you get to small enough pieces that you can just look at it and see it does what you want then you are done.

---

<div class="post-metadata">

**Author:** ![carol.ramsey](https://avatars.discourse-cdn.com/v4/letter/c/ac8455/32.png) [@carol.ramsey](https://forum.code.org/u/carol.ramsey)\
**Post date:** [July 7, 2020, 6:34pm UTC](https://forum.code.org/t/readrecords-issue/32827/11 "2020-07-07T18:34:55Z")

</div>

Don,

Thanks for the info!

I’m focused on why readRecords isn’t working right now. Do you have ideas about why it isn’t working? The code hangs up, with the debugger buttons disabled, when it gets to the readRecords statement. The table “Students” exists, the records were originally created with the createRecord on line 60.

Do you have an idea?

Thanks!  
Carol

---

<div class="post-metadata">

**Author:** ![jdonwells](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.code.org/jdonwells/32/7900_2.png) [@jdonwells](https://forum.code.org/u/jdonwells)\
**Post date:** [July 8, 2020, 3:31pm UTC](https://forum.code.org/t/readrecords-issue/32827/12 "2020-07-08T15:31:56Z")

</div>

It does work. [https://www.loom.com/share/65c3846f3cbf43c7ab8475d6af142f45](https://www.loom.com/share/65c3846f3cbf43c7ab8475d6af142f45)

There is something other than code going wrong.

---

<div class="post-metadata">

**Author:** ![carol.ramsey](https://avatars.discourse-cdn.com/v4/letter/c/ac8455/32.png) [@carol.ramsey](https://forum.code.org/u/carol.ramsey)\
**Post date:** [July 8, 2020, 4:20pm UTC](https://forum.code.org/t/readrecords-issue/32827/13 "2020-07-08T16:20:40Z")

</div>

Don,

Oh my, that is so strange.

I cleared my cache and cookies and restarted my browser. Now it works.

Well, it’s good to see that happen, so I’ll know how to help students if it happens with their code.

Thank you for all your time! I appreciate it very much!

Carol
