0

On the HTML side:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="Content-Language" content="en" />
<style>
p.serif{font-family:"Times New Roman",Times,serif;}
p.sansserif{font-family:Arial,Helvetica,sans-serif;}
</style>
<link rel="stylesheet" href="style/main.css" type="text/css">   
<title>PDS Jobs</title>
</head>
<script src="/_utils/script/sha1.js"></script>
<script src="/_utils/script/json2.js"></script>
<script src="/_utils/script/jquery.js"></script>
<script src="/_utils/script/jquery.couch.js"></script>
<script src="vendor/couchapp/jquery.couchLogin.js"></script>
<script src="vendor/couchapp/jquery.couchProfile.js"></script>
<script src="script/turboapp.js"></script>

The following code is intended to be a couchapp, and is part of "turboapp.js":

db = $.couch.db("testdb3");
var PMdata = new Object();
for (i in values) {
    PMdata[values[i]] = new Array();
}
db.view("turbologviewer/pm", {
    reduce : false,
    success : function(data) {
        $(data.rows).each( function (index, item) {
            if (PMdata.hasOwnProperty(item.key[0])) {
                 if (item.key[1] == 0) {
                    PMdata[item.key[0]][0] = item.value;
                 } else if (item.key[1] == 1) {
                    PMdata[item.key[0]][1] = item.value;
                 }
            }
        });
    }
});
for (i in values) {
  alert("Job " + values[i] + "\n" + 
        " Values1: " + PMdata[values[i]][0] + "\n" + 
        "   Values2: " + PMdata[values[i]][1] + "\n");
}

Is intended to take selected keys stored in "values". For these keys data values from a view are supposed to be stored in PMdata. Effectively this code is joining the data of two documents. Any suggestions on how to do this would also be greatly appreciated.

When I run this normally, with two entries in "values", I get "Values1: undefined \n Values2: undefined \n" for the first alert, and good data for the second alert.

When I run this under the firefox debugger, and I set a breakpoint at the alert, both alerts show perfectly good data!

What is going on?

Thanks, Gustavo Tellez

  • if `db.view` is an async function, then you are running your for loop before the your ajax method has completed, and by the second iteration it has finished and finally loaded the data – Patrick Evans Aug 13 '14 at 03:10
  • I thought that might be the case! Native jquery has the ability to add "async:false" to the ajax methods. Any idea how I might be able to to this to the couchapp view function? – Gustavo Tellez Aug 13 '14 at 11:22
  • I personally would suggest against using synchronous ajax methods, unless absolutely necessary, because if they take long they will tie up the UI and look like the browser has frozen. I say use a callback method or look into using promises. I do not know couchdb enough to know if there is a way to set a synchronous ajax call – Patrick Evans Aug 13 '14 at 11:32
  • Rewriting the code using jquery directly and async:false worked. It uses now: $.ajax({ url: DATABASE + "/_design/turbologviewer/_view/pm", async: false, success: ... }); How would I code that using a callback method? – Gustavo Tellez Aug 13 '14 at 12:06

2 Answers2

0

The problem above is indeed due to async operation of db.view. The solution, as best as I can tell, is to move the loop at the end inside of the success function as follows:

    db.view("turbologviewer/pm", {
     reduce : false,
     success : function(data) {
     $(data.rows).each( function (index, item) {
       ...
       doWorkFunction(PMdata);
    });

A new function (doWorkFunction) would be added. This forces the synchronization between the processing of the HTTP get data. Any function typed after db.view, will be executed asynchronously!

0

It turns out that there are at least two other solutions to this problem. Both involve taking action after the jQuery AJAX calls have completed.

First solution, moving the for loop into an ajaxStop as follows:

    $(document).ajaxStop(function () { for (i in values) { ... } });

The second approach is to use:

    $.when( db.view( ... ) ).then(function () { for (i in values) { ... } });

I am not certain whether the second method will work, only because of jQuery vs couchapp version incompatibilities. But in principle both approaches will work.