skip to Main Content

Have looked around and can’t quite find the answer. I am trying to run a promise which executes a fulfil statement once all facebook api pages have been iterated through and saved to an array.

I know the function’s ugly but I’m having a go to see how far I can get with promises.

function pageThroughLikes(facebookPostArray) {
  var testArray = []
  return new Promise(function (fulfill, reject) {
    facebookPostArray.forEach(function(array) {
      array.forEach(function(innerObject) {
        if ('likes' in innerObject) {
          if ('paging' in innerObject.likes) {
            if ('next' in innerObject.likes.paging) {
              nextPage = innerObject.likes.paging.next;
              currentPostId = innerObject.id;
              currentDataLength = innerObject.likes.data.length;
              i = 0;
              do{
                $.get(nextPage, function(nextLikePageData) {
                  likeData = {};
                  likeData.id = currentPostId;
                  likeData.likes = {};
                  likeData.likes.data = nextLikePageData.data
                  likeData.likes.paging = nextLikePageData.paging
                  console.log(likeData)
                  testArray.push(likeData);
                  facebookPostArray.push(testArray);
                  console.log('pushed to postArray')
                })
                i += 1;
                } while (currentDataLength != 0 && i > 10)
              }
           }
         }
      })
   });
   fulfill();
   console.log('paged through likes')
 })
}

At the moment once this function has completed I would like to run a ‘test’ function which converts my resulting array into CSV format and downloads a CSV file.

Here’s my test function:

function test() {
  var convertedPostCSV = convertArrayOfObjectsToCSV(postArray);
  downloadCSV(convertedPostCSV);
}

And here’s my running order for functions:

$(document).ready(function() {
  getPostLikes().then(function() {
    pageThroughLikes(postArray).then(function() {
      test();
    });
  });
});

What I’m struggling with is that my ‘test()’ function is running before the data from new pages of likes is added to my ‘facebookPostArray’, or before the pageThroughLikes function ends.

Hoping someone can give me some advice/point me in the right direction.

EDIT

Ok, I have reformatted my code as @Winter Soldier has suggested but I’m still getting an uncaught error for the processData function.

Here’s my code:

function pageThroughLikes(facebookPostArray) {
 console.log('paging through likes')
 var testArray = []
 var promiseList = [];
 return new Promise(function (fulfill, reject) {
   facebookPostArray.forEach(function(array) {
       array.forEach(function(innerObject) {
         if ('likes' in innerObject) {
           if ('paging' in innerObject.likes) {
             if ('next' in innerObject.likes.paging) {
               nextPage = innerObject.likes.paging.next;
               currentPostId = innerObject.id;
               currentDataLength = innerObject.likes.data.length;
               i = 0;
                 do{
                   promiseList.push(
                     $.ajax({url : nextPage
                       }))
                       i += 1;
                     } while (currentDataLength != 0 && i > 10)
                }
            }
        }
   });
   return promiseList;
   console.log('paged through likes')
})

 processData = function(nextLikePageData){
    likeData = {};
                  likeData.id = currentPostId;
                  likeData.likes = {};
                  likeData.likes.data = nextLikePageData.data
                  likeData.likes.paging = nextLikePageData.paging
                  console.log(likeData)
                  testArray.push(likeData);
                  facebookPostArray.push(testArray);
                  console.log('pushed to postArray')
  return likeData;
}

$(document).ready(function() {
  getPostLikes().then(function() {
  $.when.apply(pageThroughLikes(postArray), this).done(function() {

    var testArray = []
    $.each(arguments, function(k, v){
        var dt = processData(v[0]);
        testArray.push(dt);
        facebookPostArray.push(dt);
    });
    console.log(testArray)
    test(testArray); // OR
    test(facebookPostArray);
   });
 });
});

function test(postArray) {
  var convertedPostCSV = convertArrayOfObjectsToCSV(postArray);
  downloadCSV(convertedPostCSV);
}

EDIT 2.0

Here’s my full code in all its ugliness. Just for reference. Figure the issue could be with something I have hidden away somewhere in the rest of my code so potentially worth showing you in full…

var facebookKey = config.FACEBOOK_KEY;

// ASSIGN QUERY TO VARIABLE

var likePage = getQueryVariable("likePage");
var sinceDate = getQueryVariable("sinceDate");
var likeArray = [];
var postArray = [];


function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split('&');
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split('=');
    if (pair[0] == variable) {
      return pair[1];
    }
  }
  alert("Query Variable " + variable + " not found");
}

console.log("Page Search: " + likePage);
console.log("Since: " + sinceDate)

// FIND DATA FOR FACEBOOK PAGE POSTS SINCE CHOSEN DATE 

$(document).ready(function() {
  getPostLikes().then(function() {
  $.when.apply(pageThroughLikes(postArray), this).done(function() {
    var testArray = []
    $.each(arguments, function(k, v){
        var dt = processData(v[0]);
        testArray.push(dt);
        facebookPostArray.push(dt);
    });
    console.log(testArray)
    test(testArray); // OR
    test(facebookPostArray);
   });
 });
});

function test(postArray) {
  var convertedPostCSV = convertArrayOfObjectsToCSV(postArray);
  downloadCSV(convertedPostCSV);
}

function getPostLikes(response) {
  return new Promise(function (fulfill, reject) {
    $.get("https://graph.facebook.com/v2.8/"+ likePage + "?fields=access_token,posts.since(" + sinceDate + "){likes{id}}&access_token=" + facebookKey, function (facebookData) {

      var likePageId = facebookData.id;
      var testPostArray = [];
      if ('posts' in facebookData) {
        var nextPage = facebookData.posts.paging.next;
        var check = 0;

        postArray.push(facebookData.posts.data);

        var currentDataLength = " "
        var i = 0
        if ('paging' in facebookData.posts) {
          console.log("new page available");
          do {
            $.ajax({
              async: false,
              type: "GET",
              url: nextPage,
              success: function(nextPageData) {
                console.log("New Page Accessed: " + nextPage)
                i++;
                console.log("Page Number: " + i)
                testPostArray.push(nextPageData.data);
                if ('paging' in nextPageData) {
                  nextPage = nextPageData.paging.next;
                  console.log("next page assigned");
                }
                currentDataLength = nextPageData.data.length;
                console.log(currentDataLength);
              }
            });
            console.log("DATA LENGTH: " + currentDataLength);
          } while (currentDataLength > 0);
          testPostArray.forEach(function(element) {
            console.log(element)
            postArray.push(element);
            fulfill();
          });
        }
      } else {
        console.log('Error: No facebook posts since this date!')
        reject();
      }
      console.log(postArray)
    });
  })
};
console.log("Downloading...")


function pageThroughLikes(facebookPostArray) {
 console.log('paging through likes')
 var testArray = []
 var promiseList = [];
   facebookPostArray.forEach(function(array) {
       array.forEach(function(innerObject) {
         if ('likes' in innerObject) {
           if ('paging' in innerObject.likes) {
             if ('next' in innerObject.likes.paging) {
               nextPage = innerObject.likes.paging.next;
               currentPostId = innerObject.id;
               currentDataLength = innerObject.likes.data.length;
               i = 0;
                 do{
                   promiseList.push(
                     $.ajax({url : nextPage
                       }))
                       i += 1;
                     } while (currentDataLength != 0 && i > 10)
              }
             }
           }
         })
   });
   console.log('paged through likes')
   return promiseList;
}

 processData = function(nextLikePageData){
    likeData = {};
                  likeData.id = currentPostId;
                  likeData.likes = {};
                  likeData.likes.data = nextLikePageData.data
                  likeData.likes.paging = nextLikePageData.paging
                  console.log(likeData)
                  testArray.push(likeData);
                  facebookPostArray.push(testArray);
                  console.log('pushed to postArray')
  return likeData;
}


  // AUTO DOWNLOAD CSV FILE

  function downloadCSV(args) {
    var data, filename, link;
    var csv = convertArrayOfObjectsToCSV(postArray);

    if (csv == null) return;

    filename = args.filename || 'export.csv';

    if (!csv.match(/^data:text/csv/i)) {
      csv = 'data:text/csv;charset=utf-8,' + csv;
    }
    data = encodeURI(csv);

    link = document.createElement('a');
    link.setAttribute('href', data);
    link.setAttribute('download', filename);
    link.click();
  }
  // CONVERT FACEBOOK POSTS OBJECTS TO CSV FORMAT

  function convertArrayOfObjectsToCSV(args) {
    var result, ctr, keys, columnDelimiter, lineDelimiter, data;

    data = args || null;
    if (data == null || !data.length) {
      return null;
    }

    columnDelimiter = args.columnDelimiter || ',';
    lineDelimiter = args.lineDelimiter || 'n';

    keys = Object.keys(data[0]);

    result = '';
    result += "user_id" + columnDelimiter + " post_id" + columnDelimiter + " page_id";
    result += lineDelimiter;

    data.forEach(function(item) {
      item.forEach(function(post) {
        if ('likes' in post) {
          var likeArray = post.likes
          likeArray.data.forEach(function(like) {
            result += like.id + columnDelimiter + post.id.split('_').reverse() + lineDelimiter;
          });
        } else {
          result += columnDelimiter + post.id.split('_').reverse() + lineDelimiter;
        };
      });
    });
    console.log('converted to CSV')
  return result;
  }

EDIT 3.0

Function is almost fixed, only issue is that its not looping. Runs perfectly once though!

function pageThroughLikes(facebookPostArray) {
 console.log('paging through likes')
 var testArray = []
 var promiseList = [];
 // return new Promise(function (fulfill, reject) {
   facebookPostArray.forEach(function(array) {
       array.forEach(function(innerObject) {
         if ('likes' in innerObject) {
           if ('paging' in innerObject.likes) {
             if ('next' in innerObject.likes.paging) {
               nextPage = innerObject.likes.paging.next;
               currentPostId = innerObject.id;
               currentDataLength = innerObject.likes.data.length;
               i = 0;
                 do{
                   promiseList.push(
                     $.ajax({url : nextPage
                       }).then(function(data, b, promise){
                       data.id = currentPostId;
                       if ('paging' in data) {
                         if ('next' in data.paging) {
                           nextPage = data.paging.next;
                         }
                       }
                       console.log(nextPage)
                       return promise;
                       }))
                       i += 1;
                       console.log(i)
                     } while (currentDataLength != 0 && i > 10)
              }
             }
           }
         })
   });
   console.log('paged through likes')
   return promiseList;
}

Edit 4.0

Here’s my current code…

Almost everything’s finally working, managed to get a bunch of info from loads of late night googling.

var facebookKey = config.FACEBOOK_KEY;

// ASSIGN QUERY TO VARIABLE
var likePage = getQueryVariable("likePage");
var sinceDate = getQueryVariable("sinceDate");
var likeArray = [];
var postArray = [];

function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split('&');
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split('=');
    if (pair[0] == variable) {
      return pair[1];
    }
  }
  alert("Query Variable " + variable + " not found");
}
console.log("Page Search: " + likePage);
console.log("Since: " + sinceDate)

// FIND DATA FOR DOJOAPP FACEBOOK PAGE POSTS SINCE CHOSEN DATE

$(document).ready(function() {
  getPostLikes().then(function() {
    // console.log(postArray);
  pageThroughLikes(postArray, test)
 });
});

function test(postArray) {
  var convertedPostCSV = convertArrayOfObjectsToCSV(postArray);
  downloadCSV(convertedPostCSV);
}

function getPostLikes(response) {
  return new Promise(function (fulfill, reject) {
    $.get("https://graph.facebook.com/v2.8/"+ likePage + "?fields=access_token,posts.since(" + sinceDate + "){likes{id}}&access_token=" + facebookKey, function (facebookData) {
      var likePageId = facebookData.id;
      var testPostArray = [];
      if ('posts' in facebookData) {
        var nextPage = facebookData.posts.paging.next;
        var check = 0;
        postArray.push(facebookData.posts.data);
        var currentDataLength = " "
        var i = 0
        if ('paging' in facebookData.posts) {
          console.log("new page available");
          do {
            $.ajax({
              async: false,
              type: "GET",
              url: nextPage,
              success: function(nextPageData) {
                console.log("New Post Page Accessed: " + nextPage)
                i++;
                console.log("Paging Through Posts: " + i)
                testPostArray.push(nextPageData.data);
                if ('paging' in nextPageData) {
                  nextPage = nextPageData.paging.next;
                  console.log("next page assigned: " + nextPage);
                }
                currentDataLength = nextPageData.data.length;
                console.log(currentDataLength);
              }
            });
            console.log("DATA LENGTH: " + currentDataLength);
          } while (currentDataLength > 0);
          testPostArray.forEach(function(element) {
            // console.log(element)
            postArray.push(element);
            fulfill();
          });
        }
      } else {
        console.log('Error: No facebook posts since this date!')
        reject();
      }
      // console.log(postArray)
    });
  })
};
console.log("Downloading...")


function pageThroughLikes(facebookPostArray, callback) {
 console.log('paging through likes')
 var testArray = []
 var promiseList = [];
   facebookPostArray.forEach(function(array) {
     array.forEach(function(innerObject) {
       if ('likes' in innerObject && 'paging' in innerObject.likes && 'next' in innerObject.likes.paging) {
       var nextPage = innerObject.likes.paging.next;
       console.log('new likes page assigned: ' + nextPage);
       var currentPostId = innerObject.id;
       var noMorePages = false;
       var i = 0;
       do{
         $.ajax({
           url: nextPage,
           success: function(nextLikePageData) {
             createLikeObject(nextLikePageData, currentPostId, checkForPagesOfLikes, nextLikePageData, noMorePages)
             if ('paging' in nextLikePageData && 'next' in nextLikePageData.paging) {
               nextPage = nextLikePageData.paging.next;
             }
            }
          })
         i += 1
         console.log(i)
        } while (noMorePages = false);
       }
     })
   });
   console.log('paged through likes')
   callback();
}

function createLikeObject(likeData, postId, callback, args, fail) {
  likeArrayFormat = [];
  likeObject = {};
  likeObject.likes = {};
  likeObject.id = postId;
  likeObject.likes.data = []
  likeData.data.forEach(function(like) {
    likeObject.likes.data.push(like);
  });
  likeArrayFormat.push(likeObject);
  postArray.push(likeArrayFormat);
  console.log('pushed new like data to postArray')
  callback(args, fail)
}

function pushToArray(item, array, callback) {
  array.push(item);
  callback()
}

function checkForPagesOfLikes(data, noMorePages) {
  if ('paging' in data && 'next' in data.paging) {
      return true;
      console.log('NEW PAGE FOUND')
    }
  else {
    noMorePages = true;
    console.log('NO MORE PAGES OF LIKES FOR CURRENT OBJECT')
  }
}

  // AUTO DOWNLOAD CSV FILE
  function downloadCSV(args) {
    var data, filename, link;
    var csv = convertArrayOfObjectsToCSV(postArray);
    if (csv == null) return;
    filename = 'export.csv';
    if (!csv.match(/^data:text/csv/i)) {
      csv = 'data:text/csv;charset=utf-8,' + csv;
    }
    data = encodeURI(csv);
    link = document.createElement('a');
    link.setAttribute('href', data);
    link.setAttribute('download', filename);
    link.click();
  }

  // CONVERT FACEBOOK POSTS OBJECTS TO CSV FORMAT

  function convertArrayOfObjectsToCSV(args, callback) {
    var result, ctr, keys, columnDelimiter, lineDelimiter, data;
    // console.log(args)
    data = args || null;
    if (data == null || !data.length) {
      return null;
    }
    columnDelimiter = args.columnDelimiter || ',';
    lineDelimiter = args.lineDelimiter || 'n';
    keys = Object.keys(data[0]);
    result = '';
    result += "user_id" + columnDelimiter + " post_id" + columnDelimiter + " page_id";
    result += lineDelimiter;
    // console.log(args)
    args.forEach(function(object) {
      // console.log(object)
      // console.log(object.length)
      if (object.length != 0) {
        object.forEach(function(item) {
          if ('likes' in item && 'data' in item.likes) {
            var postId = item.id;
            item.likes.data.forEach(function(likeId) {
              if ('id' in likeId) {
                // console.log(likeId)
                var likeArray = likeId;
                // console.log(likeArray)
                  result += likeArray.id + columnDelimiter + postId.split('_').reverse() + lineDelimiter;
              } else {
                result += columnDelimiter + postId.split('_').reverse() + lineDelimiter;
              };
            });
          }
        });
      }
    })
    console.log('converted to CSV')
  return result;
  callback();
  }

Big issue is that at the moment, convertArrayObObjectsToCSV is running before the createLikeObject function is complete. Thought callbacks would’ve worked but it seems I haven’t got something quite right.

2

Answers


  1. You need to fullfil/resolve the value that you need from promise. Call the function fulfill with a value you that you need.For example if you want to resolve an array:

    fullfill(array);
    
    Login or Signup to reply.
  2. Here might be one way to do it since you are using get call, I’ve modified to not use promise at all because ajax returns the promise anyway.

    It is a pseudo code, you might have to tweak it a bit to get it running

    function pageThroughLikes(facebookPostArray) {
      var testArray = []
      var promsieList = []
        facebookPostArray.forEach(function(array) {
          array.forEach(function(innerObject) {
            if ('likes' in innerObject) {
              if ('paging' in innerObject.likes) {
                if ('next' in innerObject.likes.paging) {
                  nextPage = innerObject.likes.paging.next;
                  currentPostId = innerObject.id;
                  currentDataLength = innerObject.likes.data.length;
                  i = 0;
                  do{
                    promsieList.push(
                    $.ajax({url : nextPage                  
                    }))
                    i += 1;
                    } while (currentDataLength != 0 && i > 10)
                  }
               }
             }
          })
       });
       console.log('paged through likes')
       return promiseList();    
    }
    
    processData = function(nextLikePageData){
        likeData = {};
                      likeData.id = currentPostId;
                      likeData.likes = {};
                      likeData.likes.data = nextLikePageData.data
                      likeData.likes.paging = nextLikePageData.paging
                      console.log(likeData)
                      testArray.push(likeData);
                      facebookPostArray.push(testArray);
                      console.log('pushed to postArray')
      return likeData;
    }
    
    $(document).ready(function() {
      getPostLikes().then(function() {
      $.when.apply(this, pageThroughLikes(postArray)).done(function() {
        //debug to examine the arguments object, you'll notice its an array of arrays
        var testArray = []
        $.each(arguments, function(k, v){
            var dt = processData(v[0]);
            testArray.push(dt);
            facebookPostArray.push(dt);         
        });
        console.log(testArray)
        test(testArray); // OR
        test(facebookPostArray);
       });
     });
    });
    
    function test(postArray) {
      var convertedPostCSV = convertArrayOfObjectsToCSV(postArray);
      downloadCSV(convertedPostCSV);
    }
    

    EDIT:

    • The arguments is a default object returned by the jquery $.when
      function.
    • This is a collection of subarrays and each subarray consists of data,
      status & promise object.
    • I’m assuming that you need to consolidate the data from all the get
      calls into a testArray so, that is what is being done in the when
      call
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search