0

I am building a Cordova app for Android. I have to parse a JSON that consists of posts. Each post has text (title, description, category etc.) and images (an array of images - can be one or more). My aim is to store the JSON data for offline use (save to SQLlite database). Right now the example code below works, but the sequence is not how I expected to be:

  1. request JSON (ok)
  2. Wait for all promises (ok)
  3. Parse JSON (finishes before all the images are downloaded)
  4. Store to database the information but the images still downloading (in background thread - no harm for the UI).

What I would like to have is to store to database, when all the images have been downloaded. I' ve tried many things such as replacing the second for-loop with a recursive function (to handle the async function as stated here) and many other similar approaches but I believe that the problem starts from the 1st for loop which doesn't wait for the checkCache to finish. What do you think? How can I overcome this issue? If you need any further explanation just ask me.

My setup is: Cordova 4.0.0, Angular 1.3.1 and ImgCache 1.0

My approach is:

1st. Request JSON:

promise1 = $http({method: 'GET', url: baseURL + options1};
promise2 = $http({method: 'GET', url: baseURL + options2};
//...

2nd. Wait for all promises

return $q.all([promise1,promise2,...]).then(function(data){
   var promise1size = data[0].data.posts_number;//posts.length;
   parseJSON(data[0],promise1size,'category1');
   var promise2size = data[1].data.posts_number;//posts.length;
   parseJSON(data[1],promise1size,'category2');

  //similar for the rest promises
});

3rd. Parse JSON

function parseJSON(respdata,size,category){            
        console.log("Parsing "+size+" "+category);
        for(i=0;i<size;i++){
            var item = {};
            item ["id"] = respdata.data.object[i].id;
            item ["title"] = respdata.data.object[i].title;
            item ["description"] = respdata.data.object[i].description;

            var jsarray = respdata.data.object[i].categories;
            item ["category"] = jsarray[0].title;
            item ["catid"] = jsarray[0].id; 

            //Other JSON keys here similar as above

            //Here it starts...                
            var jsattachement = respdata.data.object[i].attachments;
            var atsize = jsattachement.length;
            if(atsize>0){   
                var images=[];
                for(j=0;j<atsize;j++){
                    (function(j){checkCache(jsattachement[j].url)}(j));//here is the problem
                    multimedia.push({title:item["title"], src:ImgCache.returnCachedURL(jsattachement[j].url), w:400,h:300});               
                    images.push({title:item["title"],src:ImgCache.returnCachedURL(jsattachement[j].url),w:400,h:300});
                }
                item ["attachement"] = images;
            }else
                item ["attachement"] = [];

            if(category=='category1')
                response.category1.push(item);
            else if(category=='category2')
                response.category2.push(item);
            //else if...
            //else if...
        }
    }
};

checkCache function:

function checkCache (imgsrc){
    ImgCache.isCached(imgsrc, function(src, success) {
        if(!success){
            ImgCache.cacheFile(src, function(){});
        }
    });
};

4th. Store to database

Here I save the parsed information to the database. On step 3 I use the returnCachedURL function for the images (which is not asynchronous) so to have the local path of the image ready even if it might not have been downloaded yet (but eventually will).

Community
  • 1
  • 1
JcDenton86
  • 933
  • 1
  • 12
  • 32

1 Answers1

0

I did this:

Similar to you but, use update sql to store the image for every downloaded image. Then, I found that some of my users want to play with me, they disconnect the internet connection in the middle of image downloading! so that I have incomplete record in the sql! Jesus!

then I change to this: I create a temporary global var. e.g. tempvar = {}, then: tempvar.data1 = 'hello', tempvar.preparedatacompleted = true, tempvar.ImagesToBeDownload = 5, tempvar.ImagesDownloaded = 0, tempvar.imagearray = ......

then, everytime image downloaded, add 1 to the number, if that no. = total no., call the function that save all data and images in this tempvar to the sql.

Kenneth Li
  • 1,632
  • 1
  • 14
  • 19