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
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:
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
EDIT:
function.
status & promise object.
calls into a testArray so, that is what is being done in the when
call