angular js getting out variable from $http is service - javascript

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
});
}
}]);

Related

Objects returned from promise are undefined

I am trying to wrap the getstream API in an angular service (factory)
Here is my code:
.factory('FeedStream', function($http, $q) {
var client = stream.connect('xxxxxxxxxxx');
return {
feed : function() {
$http.get('/api/feed/auth/')
.success(function(auth) {
var user_feed = client.feed('user', auth.user, auth.token);
console.log(user_feed.get());
user_feed.get().then(function(data) {
console.log(data);
return data;
})
})
},
}
First I get the user_id and auth token from my server using the endpoint /api/feed/auth/. This data is returned in an angular promise.
Next, I use this data to call the getstream api to get the user_feed object. If I return this object (user_feed) it is undefined in the controller. If I print it to the console here in the service, it has the correct value. I've noticed that the print happens half a second or so after the return. Why is the assignment of this variable happening asynchronously?
Now if I call the get method on this user_feed object inside a console.log statement, a Javascript promise object is printed out. If I return user_feed.get() it returns undefined to the controller. If I call it here in the service like in my code above, and return the data object in the promise then statement, it returns undefined to the controller. However if I print the data object, it has the correct value.
Why can't I return any objects from this service? Am I missing some fundamental aspect of using promises?
You haven't returned feed promise object as well as data haven't been returned from feed method correctly. So for achieving the same thing do use .then over $http to maintain promise chaining
Code
return {
feed : function() {
//return `$http.get` promise
return $http.get('/api/feed/auth/')
.then(function(response) {
var auth = response.data;
var user_feed = client.feed('user', auth.user, auth.token);
console.log(user_feed.get());
//return `$http.get` to return internal promise
return user_feed.get().then(function(data) {
console.log(data);
return data;
})
})
},
}
Controller
FeedStream.feed().then(function(data){
console.log("data returned by user feed", data)
})

Multiple service http calls using AngularJS

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;
}

angularjs Variable cannot be accessed out side function call

Recently I started learning AngularJS. My problem is as follows.
I cannot access the data returned by $http.get() out side the method call.
Code :
(function(){
var productApp = angular.module('productApp', []);
productApp.controller('ProductController', ['$http', function($http){
var store = this;
store.products = [];
$http.get('http://localhost:8080/VeggieFresh/veggie/product/1')
.success(function(data){
store.products = data;
console.log(data);
});
console.log(store.products);
}]);
})();
When I print data inside $http.get() method, it could be printed without any problem, but when i try to print it outside method; it displays empty array.
I guess because of this I cannot access this data on HTML as well.
Any help in this regards is highly appreciated.
Since $http success is a asynchronous call you wont get data immediately outside the function you can call a function for "success" function , or use a callback function
As far as your code is concerned, you can save data on $scope variable
$http.get('http://localhost:8080/VeggieFresh/veggie/product/1')
.success(function(data){
$scope.store.products = data;
//console.log(data);
});
The success function runs async, so you will get the result inside success function.
Following code worked for me.
productApp.controller('ProductController', ['$http', function($http){
var store = this;
store.products = [];
var promise = $http.get('http://localhost:8080/VeggieFresh/veggie/product/1');
promise.success(function(data){
store.products = 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(){/*...*/});

In AngularJS, how do I automatically update a value fetched via ajax?

I want to make a function which fetches some info from an ajax URL. E.g in my service, I would have the following method:
this.getFavColor = function(id)
{
return $http.get('/colors/get/' + id);
}
And in my controller, I would do the following:
$scope.favColor = UserService.getFavColor( id );
The problem however is, $scope.favColor will be assigned a promise in this case, and the only way to actually change it to the value returned by ajax, is to set a .success() callback on the promise and use it to update the value.
However, this is quickly becoming cumbersome if I have a lot of things that have to be fetched via ajax. Is there any shortcut, such as may be doing this?
this.getFavColor = function(id, variableToChange)
{
return $http.get('/colors/get/' + id).success(function(jsonResult)
{
variableToChange = jsonResult.favColor;
});
}
And then doing the following in the controller:
UserService.getFavColor( id, $scope.favColor );
Will this method actually work?
Note: I've already considered $resource but I cannot set up a REST api for my ajax, so please don't suggest it.
The way $resource does this is by returning an empty object immediatly and then adding data to this object once the response arrives from the server. That's why $resource can only return objects or arrays, not primitives.
ng-bind (and the shorthand {{ }}) actually resolves promises though, so this might be a better solution. I've created a plnkr with three different examples: http://plnkr.co/edit/WOrU5eMOmsgK4wuiSCHu?p=preview
// data.json: {"color":"Blue"}
app.service('UserService',function($http, $q){
return {
// return value can be accessed by {{value.data.color}}
getFavColor: function(id){
return $http.get('data.json');
},
// return value can be accessed by {{value}}
getFavColorWithQ: function(id){
var def = $q.defer();
$http.get('data.json').success(function(data){
def.resolve(data.color);
});
return def.promise;
}
// return value can be accessed by {{value.color}}
,resourceExample: function(id){
var response = {};
$http.get('data.json').success(function(data){
response.color = data.color;
});
return response;
}
}
});

Categories