using promise in http request in angular - angularjs

the problem is when I use $http or $resource to retrieve data, it is successfully retrieve and bind to view, but when I use promise the data come to client but it does not bind to the view.
here is my code:
//view
<div class="pull-left span6" >
<h3>{{Name}}</h3>
<ul>
<li ng-repeat="type in typeList">
<span>{{type.Title}}</span>
</li>
</ul>
//controller
var proxyControllers = angular.module('httpProxyControllers', []);
proxyControllers.controller('TypeListController',
function TypeListController($scope, typeListData) {
$scope.Name = 'Type List Addresses';
$scope.typeList = typeListData.getTypeList();
$scope.typeList.then(function(data){
console.log('data received');
console.log(data);
},function(status){
console.log(status);
});
});
//service
var proxyServices = angular.module('httpProxyServices', ['ngResource']);
proxyServices.factory('typeListData' , function($http, $q){
return{
getTypeList : function(){
var deferred = $q.defer();
$http({method : 'GET' , url: '/data/getTypeList'})
.success(function(data, status, headers, config){
deferred.resolve(data);
})
.error(function(data, status, headers, config){
deferred.reject(status);
});
return deferred.promise;
}
}
});
in then block of controller when i log data to console, it shows that data comes back successfully but nothing happen to my view and my view shows nothing actually.
thanks in advance,

You need to assign data to $scope.typeList
//initialize with empty array
$scope.typeList = [];
typeListData.getTypeList().then(function(data){
//initialize with received data
$scope.typeList = data;
console.log('data received');
console.log(data);
},function(status){
console.log(status);
});

Related

Getting ModelAndView data in angular js controller

I am trying to get the model data in angular js ,but not able to get it . I printed the value on spring mvc side .The data is getting stored and is retrieved successfully with the given key.Can anyone tell me how can I achieve this .
My controller-
#RequestMapping(value = "/home.web", method = RequestMethod.GET, produces = {
"application/json" })
public ModelAndView getUSCity(#RequestParam ("statechoice") String statechoice) {
List<String> msa = new ArrayList<String>();
msa = msaService.getMsaCodes(statechoice);
/*ModelAndView model = new ModelAndView("Home");
model.addObject("cities",msa);
System.out.println(model.getModel().get("cities"));*/
//return msa;
return new ModelAndView("Home", "cities",msa);
}
My angular js -
function MyController($scope, $http) {
$scope.getPersonData = function() {
$http({
method : 'GET',
url : 'home.web'
}).success(function(data, status, headers, config) {
alert(data);
$scope.cities = data;
}).error(function(data, status, headers, config) {
console.log("error");
// called asynchronously if an error occurs
// or server returns response with an error status.
});
};
};
Split your code into controller and service because you should not do api calls from cotroller directly(best case). Services should be used. Controllers are only be used to controlling model to show it in the view.
myService.js
app.service('myService', ['$http', '$q', function($http, $q){
return {
getPersons: function(obj) {
var deferred = $q.defer();
$http({
method : obj.method,
url : obj.url
}).then(function(response) {
deferred.resolve(response);
}, function(error) {
alert(error);
deferred.reject(error);
// called asynchronously if an error occurs
// or server returns response with an error status.
});
return deferred.promise();
};
}
});
myController.js
function MyController('MyController', ['$scope', 'myService', function($scope, myService){
$scope.persons = [];
var obj = {method: 'GET', url: 'home.web'};
myService.getPersons(obj).then(function(response){
$scope.persons = response.data // or $scope.persons = response check yourself
}, function(error){
alert(error);
})
}]);

Angularjs http call and saving received data to the controller instance

app.controller('sampleCtrl', function($scope, $http, nonService){
this.someVar = 'Hello World';
$http.post('funcsPHP/2.0/getConditionProductService.php',
{ 'product' : angular.toJson(this.productObj) }).
success(function(data, status, headers, config) {
$scope.saveData = data; // works fine
this.saveData = data // 'this' doesnt refer to the controller 'sampleCtrl' anymore, but to the $http instance, right ?
}).
error(function(data, status, headers, config) {
console.log("ERROR");
// log error
});
});
I am aware that I am able to save data to the $scope, but I would like to know how I would be able to save data to a controller variable, such as 'this.someVar'. Do I have to inject an instance of my controller into the $http ?
Cheers !
There are a few ways.
The easiest is to just assign a variable to point to the this value in your controller. The most common names are _this, self, and that.
So you get:
app.controller('sampleCtrl', function($scope, $http, nonService){
this.someVar = 'Hello World';
var self = this;
$http.post('funcsPHP/2.0/getConditionProductService.php',
{ 'product' : angular.toJson(this.productObj) }).
success(function(data, status, headers, config) {
$scope.saveData = data;
self.saveData = data;
})
.error(function(data, status, headers, config) {
console.log("ERROR");
// log error
});
});
The other way is to use Function#bind() for your success handler to set this correctly inside it.
That would give you:
app.controller('sampleCtrl', function($scope, $http, nonService){
this.someVar = 'Hello World';
$http.post('funcsPHP/2.0/getConditionProductService.php',
{ 'product' : angular.toJson(this.productObj) }).
success((function(data, status, headers, config) {
$scope.saveData = data;
this.saveData = data;
}).bind(this))
.error(function(data, status, headers, config) {
console.log("ERROR");
// log error
});
});
Use "Controller As" way of accessing your controllers instance variables:
<div ng-controller="sampleCtrl as ctrl">
{{ctrl.someVar}}
</div>

AngularJS : service not returning value

I'm trying to write an Angular service and it seems like there is something missing. My problem is its not returning any value to my Angular controller
getPrepTimes() method is not returning the http data
But when I check the network (via Chrome dev tools) it will correctly call the external api and return a json object as a response
#my service
'use strict';
angular.module('recipeapp')
.service('prepTimeService',['$http', function($http){
this.prepTime = getPrepTimes();
function getPrepTimes(){
$http({
url: '/prep_times/index.json',
method: 'GET'
})
.success(function (data, status, header, config){
return data;
});
};
}
]);
#controller
'use strict';
angular.module('recipeapp')
.controller('recipeCtrl', ['$scope', 'prepTimeService', function($scope, prepTimeService){
$scope.prep_time = prepTimeService.prepTime;
}]);
When I checked the method getPrepTimes() with returning a string it works. What could be missing here?
A couple things are wrong with the above. You assign this.prepTime to getPrepTimes(). The () there will invoke getPrepTimes immediately, and not when you actually call it! You also need to utilize callbacks to get your data back and use it:
angular.module('recipeapp').service('prepTimeService',['$http', function($http){
this.prepTime = getPrepTimes;
function getPrepTimes(callback) {
$http({
url: '/prep_times/index.json',
method: 'GET'
}).success(function (data, status, header, config){
callback(data);
});
};
}]);
And now use it like so:
prepTimeService.prepTime(function(data) {
$scope.prep_time = data;
});
Calls to the $http service are async, which means you need to return a promise (and not a value):
this.prepTime = function() {
return $http({
url: '/prep_times/index.json',
method: 'GET'
});
};
And on the controller:
angular.module('recipeapp')
.controller('recipeCtrl', ['$scope', 'prepTimeService', function($scope, prepTimeService){
$scope.prep_time = prepTimeService.prepTime()
.success(function (data, status, header, config){
$scope.someVar = data;
});
}]);
Wrap answer with promise:
var self = this;
var deferred = $q.defer();
self.getPrepTimes = function() {
$http({
url: '/prep_times/index.json',
method: 'GET'
})
.success(function(data, status, headers, config) {
if (data.error === undefined) {
deferred.resolve(data);
} else {
if (data.error !== undefined) {
} else {
deferred.reject(data);
}
}
}).error(function(data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
};
In controller call it:
prepTimeService.getPrepTimes().then(function(result) {
$scope.prep_time = result;
},
function(error) {
// show alert
});

Accessing data within a promise

I wan't to access the data in my controller just after the call to getAllMenuItems function:
x.factory('menuItemsData', function($http, $q){
return {
getAllMenuItems: function(){
var deferred=$q.defer();
$http({method: 'GET', url: 'data/MenuItems.json'}).
success(function(data, status, headers, config){
deferred.resolve(data);
}).
error(function(data, status, headers, config){
deferred.reject(status);
});
return deferred.promise;
}
};
});
app.controller('ctrl', function($scope, menuItemsData){
menuItemsData.getAllMenuItems().success(function(data){
console.log(data);
});
});
In this way:
app.controller('myCtrl', function($scope, myService){
myService.getAllMenuItems().success(function(res){
// access the response here.
$scope.menuItems = res.Items; // assign the menuitems.
})
});
You need to get the data from a promise like this:
menuItemsData.getAllMenuItems().then(function(data){
console.log(data);
});
menuItemsData.getAllMenuItems().then(
function(res){
//success callback
},
function(error){
//failure callback
}
);

ngTagsInput not populating from angular $http

Im a complete angularjs newbie. So hopefully I am somewhat on track.
I have a datacontext configured like
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId, ['common', '$http', datacontext]);
function datacontext(common, $http) {
var $q = common.$q;
var service = {
getCustomerGroups: getCustomerGroups
};
return service;
function getCustomerGroups() {
var groups = [];
$http({ method: 'GET', url: '/api/getgroups' }).
success(function (data, status, headers, config) {
console.log(status);
console.log(headers);
console.log(data);
groups = data;
return $q.when(groups);
}).
error(function (data, status, headers, config) {
console.log(data);
// called asynchronously if an error occurs
// or server returns response with an error status.
});
return $q.when(groups);
}
}
})();
Within my view I am using ngTagsInput
<tags-input ng-model="groups"
display-property="GroupName"
placeholder="Add Customer Group"
enableeditinglasttag="false"
class="ui-tags-input"
replace-spaces-with-dashes="false">
</tags-input>
And finally my controller
(function () {
'use strict';
var controllerId = 'customers';
angular.module('app').controller(controllerId, ['common','$scope','$http','datacontext', customers]);
function customers(common,$scope,$http,datacontext) {
var vm = this;
vm.title = 'Customers';
$scope.groups = [];
function getGroups() {
return datacontext.getCustomerGroups().then(function (data) {
return $scope.groups = data;
});
}
activate();
function activate() {
var promises = [getGroups()];
common.activateController(promises, controllerId)
.then(function() {
}
);
}
}
})();
I am not getting any errors and I can see the correct data is returned in the success method of $http. However the tag is not populated. Is it because the tag is calling the datasource before the $http has completed?
I am not sure how $q.when works, but it returns promise but does not resolve it. You should us the defer api.
So at start set
var defer = common.$q.defer();
and later in success do defer.resolve.
success(function (data, status, headers, config) {
console.log(status);
console.log(headers);
console.log(data);
groups = data;
defer.resolve(data);
and see if it works.

Resources