Search code examples
javascripttitaniumtitanium-mobile

Titanium passing data to createHTTPClient


I have a loop that parses a JSON from a request, and generates a table. Now the images on that table need to be downloaded, which is why i use a createHTTPClient request to get the images.

The issue is, i want to update the rows live as the image is downloaded.

But due to createHTTPClient being async, it fails to do that... It always gets the last row...

How do i pass the current row to the onload event?

My code goes something like:

onload: function(e) {
asjson = JSON.parse(this.responseText);
for (var i=0;i<asjson.objects.length;i++){
  var fname = asjson['objects'][i].photos[0].photo;
  var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, fname);

  var row = Ti.UI.createTableViewRow({
        title : asjson['objects'][i].name,
        hasChild : true,
        color: 'white',
        albumid : asjson['objects'][i].id,
        songid : asjson['objects'][i].id,
        id :  asjson['objects'][i].staff[0].id,
        idtype : 1
  });


  if (!file.exists()) {
var c = Titanium.Network.createHTTPClient();
    c.setTimeout(10000);
    c.open('GET','http://localhost:8000/' + fname);
    c.file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, fname);
    c.onload = function(e){        
        file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, fname);
        row.leftImage =  f1 = Titanium.Filesystem.applicationDataDirectory + '/' + fname;
    };
    c.send();
  }
}

Solution

  • So you have a couple of different options here. You could create all the rows ahead of time. Then once the images are loaded, loop over the table looking for the correct row and setting the images then.

    However I would recommend the following approach. The JSLint website has a good explanation why adding functions is a bad idea inside of a loop. JSLint

    onload: function(e){
      var asJson = JSON.parse(this.responseText);
      for(var i = 0, length = asJson.objects.length; i < length; i++){
        var fileName = asjson.objects[i].photos[0].photo;
                var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, fileName);
        var fileId = asJson.objects[i].id;
    
        var row = Ti.UI.createTableViewRow({
            title : asJson.objects[i].name,
            hasChild : true,
            color: 'white',
            albumid : fileId,
            songid : fileId,
            id :  asJson.objects[i].staff[0].id,
            idtype : 1
            });
    
        if(!file.exists()){
         var c = Titanium.Network.createHTTPClient();
          c.setTimeout(10000);
          c.open('GET','http://localhost:8000/' + fileName);
          c.file = Titanium.Filesystem.getFile(Titanium.FileSystem.applicationDataDirectory,fileName);
          c.onload = rowImageOnLoadHandler(row,fileName);
          c.send();
        }
    
      }      
    }
    

    Notice the rowOnLoadHandler function. This function will allow you to keep a reference to the row the HTTPClient request is running for.

       function rowImageOnLoadHandler(row,fileName){
        return function(){
          row.leftImage = Titanium.Filesystem.applicationDataDirectory + '/' + fileName;
        };
      }