Angular js api url in loop - angularjs

$http({method: 'GET', url: '/xxx/xxx/xas'}).success(function(data) {
$scope.website = data.websites;
});
$http({method: 'GET',url: '/xx/xasxxx?websiteId='+$scope.website.websiteId}).success(function(data) {
$scope.onlinedata1 = data.coupons;
});
I try to get websiteID from top url and pass that id in to 2nd url .my json data structure
"websites":[{
"websiteName":"Flipkart",
"websiteId":"1",
},
{
"websiteName":"asas",
"websiteId":"5",
}]
Try to pass every id one by one. I am using AngularJS v1.2.17.

Move the second HTTP call within the success callback of the first one:
$http({method: 'GET', url: '/xxx/xxx/xas'}).success(function(data) {
$scope.website = data.websites;
for (var i = 0; i < data.websites.length; i++)
{
$http({method: 'GET',url: '/xx/xasxxx?websiteId='+data.websites[i].websiteId}).success(function(data) {
$scope.onlinedata1 = data.coupons;
});
}
});
This can be simplified considering that your requests are GETs:
$http.get('/xxx/xxx/xas')
.then(function(res) {
for (var i = 0; i < res.data.websites.length; i++)
{
$http.get('/xx/xasxxx?websiteId='+res.data.websites[i].websiteId)
.then(function(res) {
$scope.onlinedata1 = res.data.coupons;
});
}
});
Please note that the above will issue one request for each website returned by the API. If you have control over the API you might want to consider accepting multiple website IDs on the second URL resource (/xx/xasxxx?websiteIds=1,5,7,12,56) so as to limit the number of requests issued by the client.

Use $q - service in module ng
A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing.

Related

AngularJS get value from API only if not already set

I have service to get some data from API and serve them to application.
Simple function like this:
getEnvironmentStatus() {
var _this = this;
var req = {
method: "GET",
url: "/api/system/hosting",
headers: {},
data: {}
}
return _this.$http(req);
}
In some other place I have:
determineHostingEnv() {
var _this = this;
this.$env.getEnvironmentStatus()
.then(function(response){
_this.EnvHositng = response.data.cloud_hosted;
}, function(error) {
});
}
If I need the same information in other place (other controller), I would need to call api again.
How can I make getEnvironmentStatus() function to call API only once and store data in local variable, so it can serve that variable next time it is asked for it, instead of calling API?
Also, what if that value will get requested a few times before the first API will return value? Can I prevent calling that API a few times?
One can cache the promise:
httpPromiseCache = null;
getEnvironmentStatus() {
var _this = this;
var req = {
method: "GET",
url: "/api/system/hosting",
headers: {},
data: {}
}
if (!_this.httpPromiseCache) _this.httpPromiseCache = _this.$http(req);
return _this.httpPromiseCache;
}
The service will only execute the HTTP request once.

Multiple GET requests in Angularjs

I want to make multiple ajax calls from different urls in football-data.org
API.
Here's my code sample:
angular.module('liveFootball', ['ionic'])
.constant('urls', {
BASE: 'http://api.football-data.org/',
BASE_API: 'http://api.football-data.org/v1/soccerseasons/',
TEAM_URL: 'http://api.football-data.org/v1/teams',
HEAD: {
'X-Auth-Token': 'e7486677a2dd4260b7aeb8a464749e80'
}
});
getAllFixtures: function(leagueID){
var getAllFixtures = {
method: 'GET',
url: urls.BASE + "fixtures?timeFrame=n14",
headers: urls.HEAD
}
return $http(getAllFixtures);
},
Is there a way I can include another url in this call?
Thanks.
It's not possible to have more than one url field in the $http config object, but you can send the three requests and use Promise.all() $q.all to await their responses. The response will be a promise which when you .then() will have an array containing all the responses.
getAllFixtures: function(leagueID){
var sources = [
urls.BASE,
urls.BASE_API,
urls.TEAM_URL
];
var promises = [];
for(var i=0; i<sources.length; i++){
promises.push($http({
method: 'GET',
url: sources[i] + "fixtures?timeFrame=n14",
headers: urls.HEAD
}));
}
return ̶P̶r̶o̶m̶i̶s̶e̶.̶a̶l̶l̶ $q.all(promises);
}
There is no way you can include another url , you have to call it again. You can use $q.all in angular to make multiple request at once.
For example:
var request = [getAllFixtures('10'), getAllFixtures('11)];
$q.all(request).then(function (value) {
},function(err){
}

ng-file-upload within ngResource ng-multiple progress

I have no clue how to dispatch multiple files into one server hit using the ngResource service module.
Below shows passing one file in the callback - that works.
However, if all the files are passed in one call to o.Upload(loParams.files...), Fiddler sees the file count correctly but each hit is missing the data of the file upload.
Then there is the entire seperate issue of showing $progress.
Has anyone besides me played around with this and gotten it working?
var o = $resource('myResource',{}, (
'Upload': {url: 'fileUpload',
method: 'POST',
isArray: false,
transformRequest: formDataObject,
head
});
return {
Upload: function (loParams, dataCallback, errorCallback) {
var laResponse = [];
for (var i = 0; i < loParams.files.length; i++) {
// copy parameters than add the file before uploading
var loFileUpload = angular.copy(loParams)
loFileUpload.files = loParams.files[i];
oDBC.Upload(loFileUpload, function (response) {
laResponse.push(response);
}, function (error) {
errorCallback(error);
});
};
}
Angular.Resource
GitHub :: ng-file-upload

AngularJs. Using $q.all for sending multiple post requests

I have an AngularJs app in which I need to make $http post calls in a loop. Here is my code:
var promisesArray = [];
for(i = 0; i < 28; i++) {
promisesArray.push($http({
method: "post",
url: "/studentanswers",
data: {
studentName: "abc",
answerImage: "sdf",
questionPrompt: 1
}
}));
}
$q.all(promisesArray).then(function(data){
console.log("success!!!!");
});
For some reason, it is not posting all the items in the collection. I am aware that browsers usually do not allow more than 6 async post calls. From what I understood, $q.all was a way around it. Also, even if I comment out the $q.all part, it doesn't matter because the post calls get executed nonetheless.
I would greatly appreciate any help!
Be aware that $q.all is not resilient. It will terminate with the first rejected promise. But that really isn't your problem.
You need to chain your posts to avoid the browser limit of simultaneous posts.
var promisesList = [];
var promiseMinusOne = $q.when();
for (var i = 0; i < 28; i++) {
//begin IIFE closure
function(i) {
//chain off promiseMinusOne
var httpPromise =
promiseMinusOne.catch (function (e) {
return e;
}) .then (function (r) {
return $http({ method: "post",
url: "/studentanswers",
data: answerList[i]
})
});
promisesList.push(httpPromise);
promiseMinusOne = httpPromise;
}(i);
//end IIFE closure
};
var chainablePromise =
promiseMinusOne.catch (function (e) {
return (e);
}) .then (function (r) {
//process the promisesList
});
Notice, that for promiseMinusOne, the use of .catch and return in order to continue the list in the event of a rejection of one of the items.

angularjs resource limit changes after first call

Problem description
Im using the angular resource to get data from my server. I've extended it a bit to make sure all of my resources have security headers.
Problem is that on the second get request and on, my get requests are sent with limit=0, and only the first get request is sent correctly (with limit=12).
Code part
This is my base resource factory (for making sure all resource contain the keys and everything):
app.factory('SecuredFactory', function($resource){
var DEFAULT_ACTIONS = {
'get': {method:'GET'},
'query': {method:'GET', isArray:true},
};
var DEFAULT_PARAMS = {
'limit': 12,
'format': 'json'
};
for(var key in DEFAULT_ACTIONS){
DEFAULT_ACTIONS[key]['headers'] = <headers object>;
}
var securedResource = function(url, paramDefaults, actions){
for (var attrname in actions) {
DEFAULT_ACTIONS[attrname] = actions[attrname];
}
for (var attrname in paramDefaults) {
DEFAULT_PARAMS[attrname] = paramDefaults[attrname];
}
var defaultResource = $resource(url, DEFAULT_PARAMS, DEFAULT_ACTIONS);
return defaultResource;
};
return securedResource;
});
And this is an example of how I creat a specific factory out of the secured one:
app.factory('QuestionFactory', function(SecuredFactory, Constants){
var url = Constants.SERVER_URL + 'question/';
var Task = SecuredFactory(url);
return Task;
});
And this is finally how I use it, for example:
// filtering example (not important for this matter):
var filtering = {author: "Daniel"};
var contents = [];
var resource = QuestionFactory;
resource.get(filtering, function (res) {
// success fetching
$scope.contents = $scope.contents.concat(res['objects']);
}
// failed fetching
, function (err) {
}
);
The requests
first request:
question?format=json&limit=12&offset=0
second request and on:
question?format=json&limit=0&offset=0
My problem was that the DEFAULT_PARAMS variable was declared as global. I didn't realize that invoking the secured factory with {limit: 0} will override the global, therefore changing the limit to 0 for ALL of my resources.
Changing the securedFactory to a service and moving the "globals" into the returned function solved it. Had to add new ofcourse before every securedService call.

Resources