Fetching Data From Multiple Facebook API's then Adding Together - javascript

JQuery Snippet
// THE FOUR URL'S TO ADD THE TOTAL SHARES
var Gal_All = "Link One";
var Gal_S_1 = "Link Two";
var Gal_S_2 = "Link Three";
var Gal_S_3 = "Link Four";
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_All,
success: function(data) {
showCount(data);
}
});
var fbshares;
var fbcomments;
function showCount(responseText) {
var json = responseText;
fbshares = json.shares;
fbcomments = json.comments;
$('#fb-share-count').html(fbshares);
if (fbcomments) {
$('#TotalComments').html(fbcomments + ' comments');
}
showTotal();
}
function showTotal() {
if (!tweets) {
tweets = 0
}
if (!fbshares) {
fbshares = 0
}
if (tweets !== undefined && fbshares !== undefined)
$('#total-share-count').html(tweets + fbshares);
}
For fetching data from one Facebook API I have achieved however my gallery is split up into four pages (Gal_All = all images and Gal_S_1, Gal_S_2, Gal_S_3 = categorized)
Alike I have achieved with my Twitter counter adding for all four pages, I would like to do for Facebook so it is not showing the shares for that page, but all four of the pages.
Please Note: Comments fetch only needs to be from Gal_All

First of all, you can request API data for multiple objects using
/?ids=http://example.com/1,http://example.com/2,http://example.com/3
Now since you want comments as well for your 4th URL, that still needs an extra API request (unless you want to fetch comments for the other three as well, just to throw them away, but that would not make much sense) – but you could use a batch request to at least get those two different API calls done with one single HTTP request. After all, the HTTP request is what takes most of the time in making a request to the API, so if speed is the factor you put the most emphasis on (and why wouldn’t you, users don’t like to be kept waiting), I think this is the best way to go. (Using a promise might be fine from a pure “aesthetic” point of view, but it doesn’t change the fact that multiple HTTP requests are quite slow.)

Use a promise:
var count = 0;
$.when(
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_All,
success: function(data) {
count += data;
}
});
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_S_1,
success: function(data) {
count += data;
}
});
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_S_2,
success: function(data) {
count += data;
}
});
$.ajax({
type: 'GET',
url: 'https://graph.facebook.com/' + Gal_S_3,
success: function(data) {
count += data;
}
});
).then(function() {
showCount();
});

Related

AJAX - Wait for data to append before looping next

I am creating a drop down list in JavaScript, I am loading the data via Ajax and JSON, at the moment my code loops through a set of departments and runs into the ajax call in each iteration.
My problem is that my data seems to be appending in a random order, its likely that its loading in the order of whichever loads quickest.
I want to be able to loop through my Ajax call and append the data in the order that I declare (for each department).
is this something that can be done?
Here is my code:
//-- Ajax --
var departments = ['Accounts', 'Commercial', 'Installation', 'Production', 'Sales'];
var i;
for (i = 0; i < departments.length; i++) {
$.ajax({
type: "POST",
url: "Default.aspx/EmployeesDropDown",
data: '{X: "' + departments[i] + '"}',
contentType: "application/json; charset=utf-8",
dataType: "text json",
async: true,
success: createdropdown,
failure: function () {
alert("FAIL!");
}
});
}
//-- Creates dropdown --
function createdropdown(data) {
...appends all the data to my drop down list...
}
Any help or advice is appreciated, thank you in advance.
EDIT: This question is different from the related ones because I need to be able to loop through the string array, rather than just iterating based on numbers.
If you want to load the departments in the order they appear in the departments array you could load them one by one, waiting for each ajax request to finish until you start the next request.
Here is an example:
var departments = ['Accounts', 'Commercial', 'Installation', 'Production', 'Sales'];
var i = 0;
function reqDep(department) {
/*
Since i can't use ajax here let's use a promise.
*/
var p = new Promise(function(res, rej) {
setTimeout(function() {
res(department)
}, 1000)
})
return p;
// This is what you would actually do.
/*
var data = '{X: "' + department + '"}'
return $.ajax({
type: "POST",
url: "Default.aspx/EmployeesDropDown",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "text json",
});
*/
}
function initDepartments(index) {
reqDep(departments[index])
// Here you would use `.done(function(data...`
// I am using `.then(function(data...`
// because of the promise.
.then(function(data) {
console.log(data)
if(i < departments.length) {
initDepartments(i)
}
})
i++;
};
initDepartments(i)

Ajax Pagination with jQuery

I need to retrieve data from an api that has a limit on the number of results being returned.
Using the total number of results found, I'm able to make additional additional ajax calls until all data is retrieved. However, I need sort all the data alphabetically before displaying it on the page.
How can I access the data within the array after ALL ajax calls have been successfully made?
Here is what I have so far:
var mydata = [];
function loadPosts() {
var api = 'http://someurl.com';
$.ajax({
url: api,
dataType: 'jsonp',
data: {
rows: 1,
},
success: function(data) {
totalNumberOfRecords = data.numFound;
for (var start = 0; start < totalNumberOfRecords; start += rows) {
$.ajax({
url: api,
dataType: 'jsonp',
data: {
'rows': rows,
'start': start,
},
success: function(data) {
$.each(data.namesList, function(index, item) {
mydata.push(item.firstName);
});
},
});
}
},
});
}
console.log(mydata);
This is an instant-noodle solution.
var numOfAjax = 0;
var numOfResolvedAjax = 0;
for (var start = 0; start < totalNumberOfRecords; start += rows) {
numOfAjax++;
$.ajax({
url: api,
dataType: 'jsonp',
data: {
'rows': rows,
'start': start,
},
success: function(data) {
$.each(data.namesList, function(index, item) {
mydata.push(item.firstName);
});
numOfResolvedAjax++;
// Check if all ajax request has been responded to sort the result.
if (numOfResolvedAjax === numOfAjax) {
sortMyData(myData);
}
},
});
}
For a perfect solution, please check in async library with a lot of functions which can help you. E.g: async.parallel may be what you need.
Honestly, if it were me with this API limit issue, I'd use the server to talk to the API ever-so-often to capture all the data into my own system - beit MySQL or Redis or whatever. Then I would use my front-end JS however I wanted without limmits

CRUD Operation using NAPA in SharePoint 2013

I am completely new to SharePoint development.
I am trying to create an app for basic CRUD operation using NAPA.
I took the reference from http://www.plusconsulting.com/blog/2013/05/crud-on-list-items-using-rest-services-jquery/.
There are some basic get commands in REST.
I am using Get All List Items From a Single List (where url is like: http://UsersrverName/site/_api/web/lists/getbytitle(‘listname’)/items)
Now for getting list items based on ODATA Query, the function is:
function getListItems(url, listname, query, complete, failure) {
// Executing our items via an ajax request
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listname + "')/items" + query,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
complete(data); // Returns JSON collection of the results
},
error: function (data) {
failure(data);
}
});
}
here, as per function arguments, I have assigned the value for url and listname, query is blank as I am selecting all items, and I have no idea what to assign for complete and failure.
So my main concern is the arguments to be passed in the function getListItems().
Kindly help. and if there is any other alternative (without using REST), then please suggest.
Basically complete and failure arguments are function callbacks. The following example demonstrates how to call the specified function:
var webUrl = 'http://intranet.contoso.com';
var listTitle = 'Documents';
var queryOptions = '';
getListItems(webUrl,listTitle ,queryOptions,
function(data){ //success callback function
for(var i = 0; i < data.d.results.length; i++){
var item = data.d.results[i];
console.log(item.Title);
}
},
function(error){ //error callback function
console.log(JSON.stringify(error));
}
);
Key points:
SharePoint REST endpoint /_api/web/lists/getbytitle('<list title>')/items returns JSON object in the following format:
(for Documents library)
Another approach that is commonly used and was introduced in jQuery 1.5 is based on the CommonJS Promises/A design:
jQuery.Deferred() provides flexible ways to provide multiple
callbacks, and these callbacks can be invoked regardless of whether
the original callback dispatch has already occurred
The same example that demonstrates how to utilize jQuery.Deferred() object:
function getListItems(url, listname, query) {
return $.ajax({
url: url + "/_api/web/lists/getbytitle('" + listname + "')/items" + query,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" }
});
}
Usage
getListItems(_spPageContextInfo.webAbsoluteUrl,'Documents','')
.done(function(data)
{
for(var i = 0; i < data.d.results.length; i++){
var item = data.d.results[i];
console.log(item.Title);
}
})
.fail(
function(error){
console.log(JSON.stringify(error));
});

Use of async on successive AJAX calls

Question here about use of successive AJAX calls and async. Its a bit messed here because of how the data is set up. I need to return listings, but the sever only returns 10 per query, and the only way to determine the total number of listings is a separate query with the boolean returnTotal as true instead of false. This returns the number of listings only, and not the listing results themselves. However, if I run the calls synchronously, the variable startItem (which increments on each loop to load data starting at the next block of listings) doesn't seem to populate before the next call finishes, and results get duplicated. Any way to avoid running both as async? Apologies if my code is batshit ridiculous, as I'm relatively new to jquery.
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem=0&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=true",
dataType: "html",
async: false,
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
$(this).find('total').each(function(){
totalList = $(this).text();
totalList = parseInt(totalList);
totalPages = totalList/10;
});
});
},
});
for (i = 0; i < totalPages; i++){
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
startItem = startItem + 10;
popResults();
},
});
}
The problem here is that you do not increment startItem until you receive a response. Your code is probably making multiple requests with startItem === 1 before the first response is even received, and so you will get some really weird behavior (probably will get duplicate responses, and you will only get the first few pages of data).
Avoid using synchronous calls because they will tie up other resources (like javascript).
In this case if you want to insure that you get the data in order, you can make it a serial chain of AJAX calls.
To get serial behavior and enjoy the benefits of AJAX, instead of using a loop make your callback function do the next AJAX request after incrementing startItem.
This is easier if you organize your code into functions. To wit:
function GetData()
{
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: GetData_Callback
});
}
function GetData_Callback(data)
{
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
startItem += 10; // increment startItem
popResults();
if (startItem / 10 < totalPages)
{
GetData(); // get next "page" of data
}
}
var startItem = 1; // global variable will be mutated by GetData_Callback
GetData(); // get first "page" of data
To do this in parallel typically requires management of the parallel responses (you can use semaphores, etc.). For example (psuedo code) you could do something like this:
var pages = [];
var totalPages = GetTotalPages(); // request via ajax like you mentioned (function not shown)
var pagesLoaded = 0;
for(var i = 0; i < totalPages; i++)
{
GetData(pageIdx);
}
function GetData(pageIdx)
{
$.ajax({ ..., success: function(data){GetData_Callback(pageIdx,data);}});
}
function GetData_Callback(pageIdx, data)
{
pages[pageIdx] = data; // assign this specific page of data
pagesLoaded++;
if (pagesLoaded === totalPages)
{
// fully loaded; trigger event or call function to render, etc.
}
}
Do you just mean without the async: false?
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem=0&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=true",
dataType: "html",
success: function(data) {
console.log('test1'); // first response ok
data=convert(data);
$(data).find('Listing').each(function(){
$(this).find('total').each(function(){
totalList = $(this).text();
totalList = parseInt(totalList);
totalPages = totalList/10;
});
});
var startItem=0;
console.log(totalPages); // total page should be equal too "loop" logged
for (i = 0; i < totalPages; i++){
console.log('loop'); // enter the loop
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: function(data) {
console.log('test2'); // number of test 2 = nb of loop = totalPages
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
startItem = startItem + 10;
popResults();
},
});
}
},
});
The problem here is that you do not increment startItem until you receive a response. Your code is probably making multiple requests with startItem === 1 before the first response is even received, and so you will get some really weird behavior (probably will get duplicate responses, and you will only get the first few pages of data).
Try this instead. It still uses your loop but it increments startItem in the loop before the next request is made to insure that all pages of data are requested.
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem=0&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=true",
dataType: "html",
async: false,
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
$(this).find('total').each(function(){
totalList = $(this).text();
totalList = parseInt(totalList);
totalPages = totalList/10;
});
});
},
});
var startItem = 1;
for (i = 0; i < totalPages; i++){
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
popResults();
},
});
// increment start item BEFORE the next request, not in the response
startItem += 10; // now the next request will be for 11, 21, 31, 41, etc...
}
You may want to get familiar with your javascript debugger to see the behavior for yourself.

Display search results from API

Hello there I'm trying to create an app to search for recipes. I've tried using the Yummly API and BigOven api, but I can't get either to work.
here is the code i have for bigOven. I can't get any search results to appear in the "results".
$(function() {
$('#searchform').submit(function() {
var searchterms = $("#searchterms").val();
// call our search twitter function
getResultsFromYouTube(searchterms);
return false;
});
});
function getResultsFromYouTube (searchterms) {
var apiKey = "dvxveCJB1QugC806d29k1cE6x23Nt64O";
var titleKeyword = "lasagna";
var url = "http://api.bigoven.com/recipes?pg=1&rpp=25&title_kw="+ searchterms + "&api_key="+apiKey;
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
alert('success');
console.log(data);
$("#results").html(data);
}
});
}
Can anyone give me instructions on how to do this?? Thank you very much.
The API is returning JSON data, not HTML. I checked the API docs, and JSONP isn't necessary.
However, when you run this code:
$('#results').html(data);
Your code is going to just put the JSON into your HTML, and that isn't going to get displayed properly. You didn't say whether console.log(data) outputs the data correctly, but I'll assume it is.
So, you'll need to transform your JSON into HTML. You can do that programmatically, or you can use a templating language. There are a number of options, including underscore, jquery, mustache and handlebars.
I recommend handlebars, but it's not a straightforward bit of code to add (the main difficulty will be loading your template, or including it in your build).
http://handlebarsjs.com/
It would depend on you which key and values you have to show to your user's and in which manner... For ex. there is even an image link, you could either show that image to your user's or could just show them the image link...
Simple <p> structure of all the key's with there value's
jQuery
$.each(data.Results, function (key, value) {
$.each(value, function (key, value) {
$("#result").append('<p>Key:-' + key + ' Value:-' + value + '</p>');
});
$("#result").append('<hr/>');
});
Your ajax is working, you just need to parse the results. To get you started:
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
// Parse the data:
var resultsString = "";
for (var i in data.Results){
console.log( data.Results[i] );
resultsString+= "<div>"+data.Results[i].Title+ " ("+data.Results[i].Cuisine+")</div>";
}
$("#results").html(resultsString);
// If you want to see the raw JSON displayed on the webpage, use this instead:
//$("#results").html( JSON.stringify(data) );
}
});
I had created a little recursive function that iterates through JSON and spits out all of the values (I subbed my output for yours in the else condition) -
function propertyTest(currentObject, key) {
for (var property in currentObject) {
if (typeof currentObject[property] === "object") {
propertyTest(currentObject[property], property);
} else {
$('#results').append(property + ' -- ' + currentObject[property] + '<br />');
}
}
}
Then I called it within your AJAX success -
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
console.log(data);
propertyTest(data); // called the function
}
});
It spits out all of the data in the JSON as seen here - http://jsfiddle.net/jayblanchard/2E9jb/3/

Categories

Resources