I'm trying to fetch data via post request and the API I'm querying from returns a maximal 50 elements. This worked great so far, but now we have some uses cases where it's mandatory to receive an higher indeterminate number of elements.
The $http-method returns a promise but I must rely on this data to make another request.
My simplified code:
var data =
"q=" + term
"×tamp=" + latest
$http({
method: 'POST',
url: url,
data: data
}).then(
function(response) {
let dataList = response.data.list;
if(dataList.length > 50)
/*TODO: new query with other timestamp-value*/
return dataList ;
},
function(response) {
if(shouldLog){
console.log("[DebuggingService] " + response);
}
}
);
Is there a way to combine multiple http requests depending on the request before?
EDIT
There is not pagination. So it's mandatory to change the timestamp value. (taking the latest timestamp of the response)
I would wrap that request in a function that can also be called recursively inside then() to return another request promise
Something like:
function getData(term, time, res = []) {
var data = "q=" + term + "×tamp=" + time
// return the $http promise
return $http({
method: 'POST',
url: url,
data: data
}).then(function(response) {
let dataList = response.data.list;
// merge new data into final results array
res = res.concat(dataList);
if (dataList.length > 50) {
const timeStampFromResponse = //????
// return new request promise
return getData(term, timeStampFromResponse, res)
}
// return final array
return res;
})
}
getData(term, latest).then(function(results) {
// all results available here
}).catch(function(response) {
if (shouldLog) {
console.log("[DebuggingService] " + response);
}
})
Why not do something like this:
var data =
"q=" + term + "×tamp=" + latest;
var amounts = 2;
url = 'https://api.github.com/search/repositories?q=topic:ruby+topic:rails';
call(url, data, checkForMore);
function call(url, data, callback) {
$http({
method: 'POST',
url: url,
data: data
}).then(function(data){
console.log(data);
console.log('------------');
callback(data);
});
}
function checkForMore(data){
if (amounts > 0){
amounts -= 1;
var newData = "q=" + term +
"×tamp=" + data.SomehowGetLastestTimestamp;
call(url, newData, checkForMore);
} else {
// Save it maybe?
}
}
This is a very rough example, and probably doesn't work but it gets you a good idea what to do.
Basically, have a callback method that is called on the .then anonymous function. Then you can pass in the data and check to see if you need to call it more. (Based on your situations). If you do, then just call the call function again, but update your data.
Related
I'm developing a Wikipedia Viewer and I'm trying to extract some data from the Wikipedia API. This is supposed to be a normal request, any idea why this method is not giving any response? I'm using fetch library.
The line console.log(data) doesn't run at all.
function getArticleList() {
var searchFor = "";
searchFor = document.getElementById('intext').value;
console.log(searchFor);
fetch("https://en.wikipedia.org/w/api.php?action=opensearch&search=" + searchFor + "&limit=5").then(function(resp) {
console.log("trySearch");
return resp.json()
}).then(function(data) {
console.log(data);
document.querySelector.artName.innerText = data.object[1];
document.querySelector.textArt.innerText = data.object[0];
document.querySelector.href = data.object[2]
})
};
From Wikimedia's documentation: 'For anonymous requests, origin query string parameter can be set to * which will allow requests from anywhere.'
The following worked for me:
fetch("https://en.wikipedia.org/w/api.php?&origin=*&action=opensearch&search=Belgium&limit=5").then(function(resp) {
console.log(resp);
return resp.json()
}).then(function(data) {
console.log(data);
Notice that I filled in my own search with 'Belgium', but your code should work with the right modifications.
Any particular reasons to use fetch library ? This can be done using simple Jquery AJAX.
function getArticleList() {
var searchFor = document.getElementById('intext').value;
var response="";
console.log(searchFor);
$.ajax({
url: "https://en.wikipedia.org/w/api.php?action=opensearch&search="+searchFor+"&limit=5",
dataType: 'jsonp',
success: function(data){
console.log(data);
response=data;
}
}).done(function(response) {
console.log(response);
document.querySelector.artName.innerText = response.object[1];
document.querySelector.textArt.innerText = response.object[0];
document.querySelector.href = response.object[2];
});
};
Right now I'm modifying my AJAX request to be asynchronous but I wanted to know if there was something similar to var reponse = $.ajax({ in success. Before I had my code as:
var response = $.ajax({
type : "GET",
url : url,
data : parameters,
cache : false,
async : false
}).responseText;
return response;
I tried doing using the first data argument but that just returns the parameters. Is there something similar I can use in success?
success : function(response) {
callBack(response);
}
Because the request is asynchronous you cannot just return the response.
jQuery uses something called "promises", which you can return instead:
function getUser(id) {
return $.ajax({
url: "/user",
data: { id:id },
});
}
So, whenever you want to get a user you just call the function:
var userRequest = getUser(123);
The userRequest variable now contains a "future promise". In other words, sometime in the future it will be ready for you to use it.
You cannot use it straight away but you can create a function that will run when it finally is ready. That is done using the .done() method:
userRequest.done(function (user) {
console.log("The user " + user.name + " has been loaded!");
});
If you, for example, also want to load the user's profile alongside the user then you can create two requests and then use the $.when() method:
var userRequest = getUser(123).
profileRequest = getProfileForUser(123);
$.when(userRequest, profileRequest).done(function (user, profile) {
console.log(user.name + " is " + profile.age + " years old");
});
Read more about promises over at jQuery.
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();
});
I'm need some help figuring out how to get back data from the second ajax call, not the first.
I have this method that calls my ajax calls
var projectWithIssues = getProjects().done(function(result) {
....
}
When I look at the results from this, I get back the results on my first ajax call(getEnt_PodType().done()). I want to get the results from the second ajax call within getProjects(). I understand the reason I'm getting the first results back is because I have the return on the first ajax call. However, If I don't have a return there. I get a undefined on the line above. How can I return the data from the second call?
function getEnt_PodType() {
var ent_PodType;
var oDataUrl = //URL to my data;
return $.ajax({
url: oDataUrl,
type: "GET",
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("ACCEPT", accept);
},
success: function (xhr, textStatus) {
}
});
}
function getProjects() {
return getEnt_PodType().done(function (res) {
var ent_PodType;
if (res.d.results != undefined) {
ent_PodType = res.d.results[0].Ent_PodType;
}
console.log("The ent pod type value is " + ent_PodType);
var QUERY_FILTER =
"$filter=Ent_PodType eq '" + ent_PodType + "'";
var url = restUrl + QUERY_FILTER;
// I want to return the results from this ajax call
$.ajax({
url: url,
type: "GET",
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("ACCEPT", accept);
},
success: function (xhr, textStatus) {
//projects = parseODataResultTest(xhr);
//return projects;
}
});
});
}
Thanks in advance!
Try utilizing pattern found at deferred.then
// first request
var request = $.ajax(url1),
chained = request.then(function( data ) {
console.log(data) // first request response data
// return second request
return $.ajax(url2)
});
chained.then(function( data ) {
console.log(data) // second request response data
// data retrieved from url2 as provided by the first request
});
var request = $.ajax("https://gist.githubusercontent.com/guest271314/23e61e522a14d45a35e1/raw/62775b7420f8df6b3d83244270d26495e40a1e9d/ticker.json"), // first request , `html` document
chained = request.then(function( data ) {
console.log(data) // `["abc"]`
// return `data` from second request
return $.ajax("https://gist.githubusercontent.com/guest271314/6a76aa9d2921350c9d53/raw/49fbc054731540fa68b565e398d3574fde7366e9/abc.txt")
});
chained.then(function( data ) {
console.log(data) // `abc123`
// data retrieved from url2 as provided by the first request
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Use .then instead of .done, it allows better chaining of functions.
Break your code apart so that the two AJAX calls are in separate functions, and have both those functions return the result of their $.ajax call. You can then use:
func1().then(func2).then(...);
func2 will be passed the result of the first AJAX call, and then the result of that will be passed to whatever function is in the final then.
In your case you can also put the call to parseODataResultTest in the chain and then the final function will (eventually) be called with the required data, i.e.:
getEnt_PodType().then(getProjects).then(parseODataResultTest).then(function(projects) {
// use projects here, and _only_ here because it won't
// be in scope or defined anywhere else
...
});
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));
});