Accessing data within a promise - angularjs

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

Related

deferred.resolve giving error TypeError: undefined is not a function

I am using angularjs and cordova tool for creating application.
I have created service, which contains code for calling APIs. and in that I want to return response to my angular controller.
My code is,
Service,
JodoModule.factory('commonServices', function ($http, $q, $rootScope) {
return {
getServiceData: function (url) {
$rootScope.loading = true;
var deferred = $q.defer();
var req = {
method: 'GET',
url: url
}
$http(req).success(function (data) {
alert("data in service = " + JSON.stringify(data.Data));
deferred.resolve(data);
}).error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
}
};
});
My controller is,
commonServices.getServiceData("My url").
success(function (data, status, headers, config) {
alert(data);
}).
error(function (data, status, headers, config) {
alert("Got error");
});
In above code, in service, its showing elert message for JSON.stringify(data.Data)); in success block, so data is comming, but its not executing deferred.resolve(data); properly...
in Web tool bar its giving me error,
ie. TypeError: undefined is not a function
My o/p is :
{"status":"SUCCESS","Message":"success","Token":"","Data":[{"Id":17,"UserId":"477f1919-6b80-4804-a325-ac0cb05bcd3e","UserName":"honey","FirstName":"honey","LastName":null,"ProfilePic":false,"Status":2}]}
How can I solve this error. ?
Ordinary $q promises don't have a .success() or .error() method, but you shouldn't be using the deferred antipattern anyway. Instead, do this:
JodoModule.factory('commonServices', function ($http, $rootScope) {
return {
getServiceData: function (url) {
$rootScope.loading = true;
var req = {
method: 'GET',
url: url
};
return $http(req).then(function (result) {
alert("data in service = " + JSON.stringify(result.data.Data));
return result.data;
});
}
};
});
Controller:
commonServices.getServiceData("My url").
then(function (data) {
alert(data);
}).
catch(function (result) {
alert("Got error");
});
Quite a bit cleaner, ay?

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

Can't return data from factory to controller AngularJS

I am having trouble returning data from a factory method to a controller.
service.js
var serverFac = angular.module('serverCom', []).factory('SmsSendService', function($http){
var transform = function(data){
return $.param(data);
}
var temp = {};
temp.sendSms = function(tempJs){
$http.post("http://localhost:8080/somepath/rest/text-messages/send/batch", tempJs ,{
transformRequest: transform
}).success(function(data, status, headers, config){
//do stuff with response
});
};
temp.login = function (tempUserPassword){
$http.post("http://localhost:8080/somepath/rest/users/authenticate", tempUserPassword ,{
transformRequest: transform
}).success(function(data, status, headers, config){
//do stuff with response
}). error(function(data, status, headers, config){
console.log(status);
});
};
temp.SimList = function (){
$http.get("http://localhost:8080/RetireesClub_server/rest/sim-cards"
).success(function(data, status, headers, config){
//do stuff with response
}). error(function(data, status, headers, config){
});
};
return temp;
});
serverFac.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form- urlencoded;charset=utf-8';
});
controller.js
function SimListController($scope, SmsSendService, SearchData, Search , $dialog , $location,$filter ){
smsSendService.simList().success(function(data){
$scope.sims= data;
}
}
Since you are handling the success callback in the controller, make your service function return a promise:
temp.SimList = function (){
return $http.get("http://localhost:8080/RetireesClub_server/rest/sim-cards")
};

AngularJS $http is not defined

I'm pretty new to with AngularJS. When I'm calling $http.get I get a $http is not defined error.
This is the content of my Module:
var demoApp = angular.module('demoApp', []);
demoApp.config(function ($routeProvider) {
$routeProvider.
when('/view1',
{
controller: 'SimpleController',
templateUrl: 'View1.html'
}).
when('/view2',
{
controller: 'SimpleController',
templateUrl: 'View2.html'
})
.otherwise({ redirectTo: '/view1' });
});
demoApp.factory('simpleFactory', function () {
var factory = {};
factory.getAnnounces = function ($http) {
$http.post("http://localhost:57034/Announce/GetAllAnnounces")
.success(function (data, status, headers, config) {
return data;
}).error(function (data, status, headers, config) {
return status;
});
};
return factory;
});
demoApp.controller('SimpleController', function ($scope,simpleFactory) {
$scope.announces = [];
init();
function init()
{
$scope.announces= simpleFactory.getAnnounces();
}
});
What am I missing here? Cheers.
You need to review your code as follows:
demoApp.factory('simpleFactory', ['$http', function ($http) {
return {
getAnnounces: function () {
$http.post("http://localhost:57034/Announce/GetAllAnnounces")
.success(function (data, status, headers, config) {
return data;
}).error(function (data, status, headers, config) {
return status;
});
}
};
}]);
There's no need to pass the $http variable in the getAnnounces method definition, because it is defined already in the scope of the factory function.
I am using parameter aliasing for AngularJS in order to avoid issues with minifiers, see 'A note on minification' on the AngularJS web site.
Note anyway that $http.post.success and $http.post.error are asynchronous and you won't be able to get the data unless you're using promises ($q), see here. Therefore you could change the code this way:
demoApp.factory('simpleFactory', ['$http', '$q', function ($http, $q) {
return {
getAnnounces: function () {
var deferred = $q.defer();
$http.post("http://localhost:57034/Announce/GetAllAnnounces")
.success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
}
};
}]);
And in the SimpleController:
demoApp.controller('SimpleController', ['simpleFactory', '$scope', function (simpleFactory, $scope) {
$scope.announces = [];
simpleFactory.getAnnounces()
.then(function(data) {
// call was successful
$scope.announces = data;
}, function(data) {
// call returned an error
$scope.announces = data;
});
}]);

Resources