Multiple GET requests in Angularjs - 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){
}

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.

PUT request in node.js using $http

I'm trying to make a PUT request to a SQL database through node.js using AngularJS. I keep getting a 400 bad request error. Not sure what's wrong with the request, since this format works using a straight $.ajax call. Any help would be appreciated
vm.approveUser = function(user_id){
console.log('in approveUser');
console.log('user_id', user_id);
$http({
method: 'PUT',
url: '/admin/approve',
data: user_id
}).then(function(){
console.log('back from the /approve');
vm.getRequests();
}); //end .then function
}; //end approveUser
Try simplifying the request and add a return statement. See if it resolves.
vm.approve = function(user_id) {
var url = '/admin/approve';
return $http.put(url, user_id)
.then(function(resp) {
vm.getRequests();
})
.catch(function(error) {
})
.finally(function() {
});
};

Angular js api url in loop

$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.

AngularJS $http ajax request is not asynchronous and causes page to hang

I have a service where I am pulling data from server. When I click the button to send out the request to server through this service, the window freezes until I receive a response from server. Is there anything I can do to make this request asynchronous ?
Here is my service.
app.factory('service', function($http) {
return {
getLogData : function(startTime,endTime){
return $http({
url: baseURL + 'getLogData',
method: 'GET',
async: true,
cache: false,
headers: {'Accept': 'application/json', 'Pragma': 'no-cache'},
params: {'startTime': startTime , 'endTime': endTime}
});
}
};
)};
HTML.
<button ng-click="getData()">Refresh</button>
<img src="pending.gif" ng-show="dataPending" />
Code
$scope.getData = function(){
service.getLogData().success(function(data){
//process data
}).error(function(e){
//show error message
});
}
While there is some argument about the pros and cons of your approach, I am thinking that the problem is answered here: AJAX call freezes browser for a bit while it gets response and executes success
To test if this in fact part of the problem, dummy up a response and serve it statically. I use Fiddler or WireShark to get the response and then save to a file like testService.json. XHR and all of it's various derivatives like $HTTP $.ajax see it as a service though the headers might be slightly different.
Use the success promise, and wrap up the log data in a set of objects that you can attach to a $scope.
So instead of having your service have a blocking method, have it maintain a list of "LogEntries".
// constructor function
var LogEntry = function() {
/*...*/
}
var logEntries = [];
// Non-blocking fetch log data
var getLogData = function() {
return $http({
url : baseURL + 'getLogData',
method : 'GET',
async : true,
cache : false,
headers : { 'Accept' : 'application/json' , 'Pragma':'no-cache'},
params : {'startTime' : startTime , 'endTime' : endTime}
}).success(function(data) {;
// for each log entry in data, populate logEntries
// push(new LogEntry( stuff from data ))...
};
}
Then in your controller, inject your service and reference this service's log data array so Angular will watch it and change the view correctly
$scope.logEntries = mySvc.logEntries;
Then in the HTML, simply do something over logEntries:
<p ng-repeat="logEntry in logEntries">
{{logEntry}}
</p>
use this code to config
$httpProvider.useApplyAsync(true);
var url = //Your URL;
var config = {
async:true
};
var promise= $http.get(url, config);
promise.then(
function (result)
{
return result.data;
},
function (error)
{
return error;
}
);

pyramid not work with angular $http post

$http({method: 'POST', url: 'http://localhost:5001/products', data: {token: $scope.product.token}}).success(
function () {
alert('success');
}
);
In the pyramid side, request.POST show that NOVars: Not a form request. Not an HTML form submission( Content-Type: application/json)
I am using cornice to provide my api(/products) and I thinks it is pyramid's problem.
Does anyone have a solution?
Angular sends the post body (data) as application/json while forms are normally sent as application/x-www-form-urlencoded. Pyramid parses the body and let you access it in request.POST when it's encoded as a normal form.
It is not be possible to represent every data encoded the Angular way (json) as a key/value pair like is provided by pyramid API.
[
1,
2,
3,
4
]
Solution on Pyramid side
It can be solved per view or globally
Per view
This is the pyramid way and the most flexible way to handle this.
#view_config(renderer='json')
def myview(request):
data = request.json_body
# deal with data.
return {
"success" : True
}
Globally
Pyramid can most likely be set to assume a body encoded as application/json is an object and its properties be put in request.POST.
Solution on Angular side
As with the pyramid side, it can be solved per request and globally.
Per request
You need to send the data the way forms are normally sent:
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
},
data: xsrf
}).success(function () {});
Globally
To send posts as form by default, configure the $httpProvider to do so.
angular.module('httpPostAsForm', [])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$httpProvider.defaults.transformRequest.unshift(function (obj) {
var str = [];
for(var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
});
}]);
Then include this module in your app:
angular.module("app", ["httpPostAsForm"]);
AngularJS $http.post is different from jquery's. The data you pass is not posted as a form but as json in the request body. So your pyramid view can not decode it as usual. You have to either:
directly access the request body and decode it in your pyramid view;
or modify your angularjs code to post your data as form content : see this other question in stackoverflow
the answer is angular $post do OPTIONS request first and then do the POST request, get data form the request.json_body
Use req.json_body if you post some json-decoded content. req.GET, req.POST, req.params only cope with from submissions. Btw, $http -> ngResource -> restangular ...
Try setting contenttype in $http, something like below.
$http(
{
url: url,
contentType: "application/json",
data: data,
method: method
})
.success(function (response) {
successcb(response);
}).error(function (data, status, headers, config) { errorcb(data); });
};
You can simply get the POST data this way:
query = json.loads(request.body)

Resources