getColumn: one common error and one subtle error explained

The most common error with getColumn by far seems to be wrapping it in [ ]s. You end up with an array (returned by getColumn) inside an array (created by [ ]) and that doesn’t do what you want at all. So just write var cats = getColumn("Cats","Name");. No ( )s and no [ ]s. I wrote a more complete explanation here Everything You Wanted to Know About App Lab Arrays, But Were Afraid to Ask.

The subtle error that can result is a race condition. A race condition happens when you have two or more segments of code running at the same time or sequentially, but randomly chosen order. The result can be different depending on which code segment finishes first.

I went to the App Lab source code to see why this might be happening. What I found is that getColumn is implemented the same as readRecords. The difference is that App Lab provides the callback function for getColumn while you provide the callback function for readRecords. What is the same is that they both do not finish reading the database when the function is called, returns, and moves to the next line of code. Instead, they finish some random amount of time after that possibly after several more lines of code have run or attempted to run. If you are immediately running code after calling getColumn that depends on the result of that getColumn it is not guaranteed to work.

You may not see this problem happening with small datasets. The database access and the callback are running in the browser’s Javascript and that is 200 times faster than App Lab’s Javascript. A call to getColumn with a small dataset can finish before the next line of App Lab code runs. However, with large datasets or several calls to getColumn one after another it is unlikely to finish in time.

What happens with a race condition can vary. The worst thing is an infinite loop. App Lab just seems to become unresponsive. No buttons seem to work. So how do you fix this problem when it crops up?

First thing is to move all the calls to getColumn to the top of the program. Get those database loads started ASAP.

Do not run any code that uses those arrays outside of onEvent callbacks or functions called by those callbacks. In other words, don’t run anything else until the user clicks or types something. Nothing runs while the database is loading. The time it takes for a person to move the mouse and click a button should be long enough for the database to load.

Let me say that again. You have code like var cats = getColumn("Cats","Name); at the top. After that you can add calls to onEvent and definitions of functions like function updateScreen () {. No code that just runs like a for loop hanging out by itself.

Do not watch a variable that holds an array returned by getColumn. A race condition within App Lab itself between getColumn and the watcher can happen.

1 Like