Multiple service http calls using AngularJS - javascript

In my controller I am calling a service with the following code:
Service.updateData(data).then(function (result) {
console.log(result);
});
In my service I am using $q to get multiple HTTP requests.
$rootScope.http_1 = $http.get();
$rootScope.http_2 = $http.get();
$q.all([$rootScope.http_1, $rootScope.http_2]).then(function(result) {
console.log(result[0], result[1]);
return result[0], result[1];
});
The code actually works as the http requests are successfully made. However, I get an error in the controller which says: TypeError: Cannot read property 'then' of undefined. I believe this is due the service not returning the promise in the correct way. Any ideas on how to resolve this would be much appreciated?

It looks like you are not returning the promise in updateData Try this:
updateData = function(data) {
$rootScope.http_1 = $http.get();
$rootScope.http_2 = $http.get();
return $q.all([$rootScope.http_1, $rootScope.http_2]);
}
You didn't return the promise, so there is nothing to call .then() on in your controller
You are returning inside the .then() function inside your service.updateData(), which doesn't do very much for you.
If you want to control it all inside the service and return a specific format, try this:
updateData = function(data) {
$rootScope.http_1 = $http.get();
$rootScope.http_2 = $http.get();
var defer = $q.defer();
$q.all([$rootScope.http_1, $rootScope.http_2]).then(function(result){
// process here to get the data how you want it, say in some new var foo
var foo = "some processed data based on result";
defer.resolve(foo);
});
return defer.promise;
}

Related

Return html response to calling function in nodejs

I've got this Node.js snippet.
var requestify = require('requestify');
// [...]
function remoterequest(url, data) {
requestify.post(url, data).then(function(response) {
var res = response.getBody();
// TODO use res to send back to the client the number of expected outputs
});
return true;
}
I need to return res content instead of true, back to the caller.
How can I do that?
In this case, the requestify's method is asyncronous, therefore, the returned value is not possible to be retrieved (since it's not generated yet).
How can I solve it? How can I send a synchronous HTTP POST request (even without requestify)?
you need to return a promise and use it in the then method of the promised returned by remoteRequest :
var requestify = require('requestify');
// [...]
function remoterequest(url, data) {
return requestify
.post(url, data)
.then((response) => response.getBody());
}
//....
remoteRequest('/foo', {bar: 'baz'}).then(res => {
//Do something with res...
});
Note that it still won't be a synchronous POST though, but you will be able to use response.getBody() when available, If this is what you wanted
You can refer to this discussion about how to use content returned from a promise How do I return the response from an asynchronous call?
As mentionned by #Logar, you can't use directly the content returned in your promise. You must call your method returning a promise first, and use .then to make the returned content available.
Example:
var requestify = require('requestify');
// [...]
// This function returns a promise, so you have to call it followed by `.then` to be able to use its returned content
function remoterequest(url, data) {
requestify
.post(url, data)
.then((response) => {
return response.getBody();
});
}
//....
//... Some other code here
//....
// Make a call to your function returning the promise
remoterequest('your-url-here', {data-to-pass-as-param})
.then((res) => { // Calling `.then` here to access the returned content from `remoterequest` function
// Now you can use `res` content here
});

angular js getting out variable from $http is service

Hi I have created a service which gets a json from a remote server, not I need to get the result and set it as a property of the service, but I don't know how to get the property out of the function
app.service('varService',['$http', function($http){
var ip = myip;
window.city = '';
$http.get('http://ip-api.com/json/'+ip)
.then(function(data) { window.city = data.data.city; });
this.city=city;
}]);
the property this.city doesn't receive any value , however when I do console.log inside .then() the value exists, how do I solve the problem, how do I get value out of $http.then()?
Because $http.get returns a promise, when you assign the city value, the request hasn't actually returned from the web server yet.
You need to return the promise from your service and instead handle your .then() callback handler in your invoking controller.
app.service('varService',['$http', function($http){
var ip = myip;
this.getIp = $http.get('http://ip-api.com/json/'+ip);
}]);
// controller
varService.getIp.then(function(data) { window.city = data.data; });
This is the recommended approach by the John Papa AngularJS Styleguide and it allows you to chain multiple promises together.
There you can't get data return by ajax as soon as you execute that line of code, you should use .then callback to retrieve data over there. You could use .then over $http call to get data from ajax.
app.service('varService',['$http', function($http){
var ip = myip;
var self = this;
self.getCity = function (){
return $http.get('http://ip-api.com/json/'+ip)
.then(function(data) {
self.city = data.data.city;
return self.city; //do return city retrieved
});
}
}]);

Function doesn't return $http response

I have created a function expression and assigned it to scope, the idea being that the function will initiate an $http request, get a property and then return it.
$scope.getRequestDigest = function () {
var url = urlParams['SPAppWebUrl'] + '/_api/contextinfo';
$http.post(url)
.success(function (res) {
return res;
});
}
However when I call $scope.getRequestDigest() it simply returns undefined, presumably because the ajax call hasn't completed yet. Is there any way to delay the return until the $http request is complete? I've tried using the .success() promise but that doesn't seem to work.
$http.post returns a promise (see $q). In order to use the result, bind res to $scope.res:
controller:
$scope.getRequestDigest = function () {
var url = urlParams['SPAppWebUrl'] + '/_api/contextinfo';
$http.post(url)
.success(function (res) {
$scope.res = res;
});
}
Then, you can use $scope.res (or res in the template) anywhere you'd like.
After the promise chain is resolved (after success), Angular will run a digest cycle and rebind everything on $scope.
Try
$scope.getRequestDigest = function () {
var url = urlParams['SPAppWebUrl'] + '/_api/contextinfo';
return $http.post(url);
}
var digestPromise = $scope.getRequestDigest();
digestPromise.then(function(response){
console.log(response.data);
});
This way you are actually returning a promise, which AngularJS implements through the $q service.
If you were to output (console.log(digestPromise)) digestPromise, you will see that you can all sorts of functions on it, like success or complete, for example.
You could use chain promise using .then
$scope.getRequestDigest = function () {
var url = urlParams['SPAppWebUrl'] + '/_api/contextinfo';
return $http.post(url) //this will return a promise
.then(function (res) {
return res.data; //on success this will return a data to caller function
});
}
Then the caller function will have call the function and get the data like this
$scope.getRequestDigest().then(function(data){
console.log(data)
//here you can get data returned from `getRequestDigest` method
})

$http in Anjgularjs: Can someone explain the flow

In an $http call, What all things we can pass in the url part, I have a server address, a user name and Password. Can i pass all as a json object?, or we have any other parameter (like url) for this.?
Can someone help me in understanding what is happening on a success call.
Specifically, the code I'm struggling with is:
app.factory('myFactory',function(){
var fact = {};
fact.getData = function(a){
$http({method:'POST',url:'http://100.100.100.100:8080/xx/xx.xx'});
$http.success(function(reply){a(reply)}
);
};
return fact;
});
See the following code, still I am not getting data from server, at the same time no errors too.
xapp.factory('loginData',function($http,$log){
var fact = {};
fact.getData = function(cred,cb){
return
$http({
method:'post',
url:'xxx.xxx.xxx.xxx:xxxx/xxxxxx',
data:cred})
.success(function(data,status,header,config){
cb(data);
})
.error(function(data,status,header,config){
$log.warn(status);
});
};
return fact;
});
xapp.controller('mainController',function($scope,$log,$http,loginData){
$scope.user = {uesr:'user',password:'123'};
loginData.getData($scope.user,function(data){
$scope.reply = data;
});
});
In the console log, I get an 'undefined'. If the http url is correct, do u see any issue?
As far as I understand, a parameter is a callback function that is executed when reply from server is received. This kills the purpose of promises that the $q service provides. Also, $http service itself does not have .success callback. It returns a promise object with .success and .error callbacks. Here's how it should be done:
app.factory('myFactory', function() {
var fact = {};
fact.getData = function() {
return $http.get('your/path/to/resource/');
}
return fact;
})
.controller('myCtrl', function($scope, myFactory) {
myFactory.getData().then(function(response){
//response.data holds your data from server
}, function(){
//this fn gets called when error happens
});
});
Some explanations: myFactory.getData() creates a new http request to the server and returns a promise object which has a method .then(successCallback, errorCallback). You can provide callbacks to the promise to be executed after request is complete.
You might get confused with my mentioned .then(successCallback, errorCallback) and .success(callback) used in your example. A generic promise that $q provides has .then method, but $http service, upon returning a promise, provides shortcuts .success() and .error() but it's the same thing in the end.
This will solve your problem of sending body.
app.factory('myFactory', function($http) {
return{
getData : function(body) {
return $http({
url: 'http://100.100.100.100:8080/xx/xx.xx',
method: 'POST',
data:body
})
}
}
});
app.controller('myCtrl', function($scope, $location, $http, myFactory){
var body ={username:uname, password:pass};
myFactory.getData(body).success(function(data){
$scope.data=data;
});
});

How to use data returned by $http request for another request in same controller using angularjs?

I am making a function that makes a http GET request, and then uses part of that response to make another http GET request. However, the data being returned by the first http GET request is wrapped in a lot of unnecessary data (maybe its a promise object), but I just need the json component of it. How do I access the json data of my response in the controller? Here is my code.
$scope.doSearch = function() {
var upcResult = Restangular.one('upc',$scope.searchTerm).get()
//the upc returns an item, so i am trying to access that part of the json by using
upcResult.item, how if I console.log that it is undefined
$scope.doAnotherSearch = function() {
var itemResult = Restangular.one('item',upcResult.item).get();
}
You can use promise chain.
var upcResult = Restangular.one('upc',$scope.searchTerm).get();
upcResult.then(function (result) {
// call other http get
return Restangular.one('item',result.item).get();
}).then(function (result) {
//....
});
I don't know if in your case Restangular.one(/*...*/).get(); returns promise but you can wrap it with $q like:
var upcResult = Restangular.one('upc',$scope.searchTerm).get();
var deferred = $q.defer();
deferred.resolve(upcResult).then(function(){/*...*/});

Categories