using the data from the post request - angularjs

I pass two dates to the post method thro controller.The service responses back with some data based on the given input. Im using $scope.onGetData to get the data from post method, inorder to display the final result but it is not going inside the $scope.onGetData. So the question is how to fetch the response data from the service and use it inside a controller, so that I can make use of it in my view.
Controller:
$scope.computationList;
$scope.onViewLoaded = function () {
computationManagementService.getComputation($scope.onGetData);
}
$scope.onGetData = function (data,response,error) {
$scope.computationList = data;
}
$scope.calculateInput=function(start,end,htmlValidation)
{
var date={'startDate':start , 'endDate':end};
if(htmlValidation){
computationManagementService.getComputation(date,function(err,response){
console.log("pass thro controller");
});
}else{
console.log("Validation Error");
}
}
});
Service:
myApp.factory('computationManagementService', function($http, settings){
var ComputationServiceFactoryObj = {};
var _getComputation= function(date,callback){
$http({
method:'POST',
url: 'localhost:/8091/date/computation',
data: date
}).success(function(data,response,config){
callback(response);
console.log(data); // data
}).error(function (data, status, error, headers, config){
if(callback) {
callback(error);
console.log(error);
}
});
}
ComputationServiceFactoryObj.getComputation= _getComputation;
return ComputationServiceFactoryObj;
});

If you are trying to use the post method's data to the view then you can try this method And it worked for me but not sure if it is correct way of using the service.
Service:
myApp.factory('computationManagementService',
function($http, $rootScope, settings){
var ComputationServiceFactoryObj = {};
var _getComputation=function(callback){
var computationData=$rootScope.finalResult;
if(callback != null){
callback(computationData);
}
}
var _postComputation= function(date,callback){
$http({
method:'POST',
url: 'localhost:/8091/date/computation',
data: date
}).success(function(data){
callback(data);
$rootScope.finalResult=data;
console.log(data); // data
}).error(function (data, status, error, headers, config){
if(callback) {
callback(error);
console.log(error);
}
});
}
ComputationServiceFactoryObj.getComputation= _getComputation;
ComputationServiceFactoryObj.postComputation= _postComputation;
return ComputationServiceFactoryObj;
});

Some good practices:
using ngResource is always preferable to the raw $http service, except for rare cases when you need some complex configuration that ngResource can't handle (I can't think of such, though). Why? It forces you yo use promises.
return promises from your service methods instead of passing callbacks. Using callbacks will force you to call $digest on your scope so that bingings are re-evaluated, which goes against the way angular works in general and may have negative performance impact as well.
In your case I'd modify the _getComputation method to simply return a promise:
var _getComputation = function(date) {
return $http({
method:'POST',
url: 'localhost:/8091/date/computation',
data: date
});
};
In your controller:
computationManagementService.getComputation(date)
.then(function(response) {
console.log(response);
$scope.someValue = response.someValue;
}, function(error) {
console.error(error);
});
I'd rather avoid injecting $scope in controllers, and use the ngController='MyController' as 'MyCtrl' syntax instead and assign values that should be accessible by views to the controller instance.

It is better not to use .success and .error methods in your service as they are not chainable, Use .then format instead. .success/error methods are deprecated in the latest Angular version 1.6.
Here is the Deprecation notice from Angular documentaion.
In your service :
var _getComputation= function(date,callback){
return $http({
method:'POST',
url: 'localhost:/8091/date/computation',
data: date
}).success(function(data,response,config){
callback(undefined, response);
console.log(data); // data
}).error(function (data, status, error, headers, config){
if(callback) {
callback(error);
console.log(error);
}
});
}
In your Controller :
computationManagementService.getComputation(date,function(err,response){
console.log("pass thro controller");
console.log(response);
}

Related

angularJS: order of promise

I have two promises:
getToken() //:get a CSFR cookie from the server
and
getUseraData() //:get user data, but it need the cookie get from getToknen() otherwise server respond with an error.
So, I know that I can do this in my controller:
getToken().then(function (result) {
getUserData(result);
});
But I know that it is not so good to run a promise inside a promise.
So: how can I exec the getUserData() promise only after that getToken is terminard and a value is returned?
There is nothing wrong with chaining promises, which is what you are doing, as long as you don't forget to return a promise, so do it like this:
var getUserDataPromise = getToken().then(function (result) {
return getUserData(result);
});
Or like this:
getToken().then(function (result) {
return getUserData(result);
}).then(function(getUserDataPromiseResult){
//here you will have the getUserData promise resolved
});
Notice that for this to work you need to return a promise. I insist: this is not a bad practice, this is a very common practice
you can use deferred function.. you need to inject $q..
create a service then add your getToken http request code.. like this
myapp.factory('myService',$q,$http){
var deferred = $q.defer();
var newVal = { 'Value': val };
var getToken = functino(){ $http({
method: 'PATCH',
url: baseService.getBaseService + 'ModuleAndParameters(' + ModAndParamsId + ')',
data: newVal
}).success(function (data, status, headers, config) {
deferred.resolve(data)
}).error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
};
return getToken;
}
then in your controller,, inject the name of your service.. and just simply do it like this..
myService.getToken().then(function(result){
getUserData(result);
})
i hope it helped..xD

Angular reference error $scope not defined

I am new to angular and I am trying to list my data in database .However I am gettin $scope not defined error..This is my code
productsService
.getProducts()
.success(function (data, status, headers, config) {
$scope.products = data;
console.log($scope.products);
})
.error(function (error) {
//Showing error message
$scope.status = 'Unable to retrieve product' + error.message;
});
In my product Service I have
return {
getProducts: function () {
return $http({
method: 'GET',
url: '/api/Products'
}).success(function (data) {
alert("success");
// console.log(data);
}).error(function (error) {
//Showing error message
alert("failed");
$scope.status = 'Unable to retrieve products' + error.message;
console.log($scope.status);
});
},
I am just getting failed alert. Please help!!!In backend I am able to get the data from database.
In an Angular service, you do not have access to the $scope, that is something you only have in directives and controllers. That is why you are getting an error about $scope being undefined.
Also, in your service you are returning a promise from your getProducts() method, yet you are also adding success and error handlers on to it. You should make up your mind whether you want to return the raw $http promise, or if instead you want to return a $q promise which is resolved with some transformed copy of the data returned in the $http().success() handler.
One final thing, if you are seeing the "failed" alert, that means your server is returning an error when you submit a request to /api/Products. If you go to that URL in your browser, does it work? You should look into why a basic GET request to that URL is not working.
You should not uses scope variables in your service, you service should only be used to get/update/share some data.
Here is how your service should look like
Service
return {
getProducts: function() {
return $http({
method: 'GET',
url: '/api/Products'
});
},
and in your controller for that service method you can have a .success() and .error() which you can use to set your error messages.
Controller
productsService
.getProducts()
.success(function (data, status, headers, config) {
$scope.products = data;
})
.error(function (error) {
$scope.status = 'Unable to retrieve product' + error.message;
});
Hope this helps.

Where in angular should I put this code?

I have an http-method that gets some data from a google spreadsheet. I want to add this to the $scope so I can output it in the DOM. Later I might make a timed loop of this so that the $scope get's updated every 5 seconds or so.
I currently run the code in app.run:
angular.module('spreadsheet2angular', []).
run(function($http){
$http({method: 'GET', url: 'http://cors.io/spreadsheets.google.com/feeds/cells/0Aq_23rNPzvODdFlBOFRYWlQwUFBtcXlGamhQeU9Canc/od6/public/values?alt=json'}).
success(function(data, status, headers, config) {
var entries = data.feed.entry;
var phraces = [];
entries.forEach(function(entry){
var cell = entry.gs$cell;
if(!phraces[cell.row]){
phraces[cell.row] = {};
}
if(cell.col == 1)
{
phraces[cell.row].name = cell.$t;
}
else if(cell.col == 2)
{
phraces[cell.row].value = cell.$t;
}
});
phraces.forEach(function(phrace){
console.log(phrace);
});
}).
error(function(data, status, headers, config) {
console.log('error');
});
});
I'm new to angular, is this the best place to run it? I would like to run it as something that is easily reusable in different projects.
I think from what you've explained, a service would be perfect. Build it out then inject it in your controller. You can then call/use that service object whenever you would like.
I would use service/factory that returns promise. So we call async service method, get back promise and parse response into controller.
If you think to use the same call in the future, you can write generic method.
By the same way, if you are going to parse response by the same way in the future, the part of logic I would put into the service as well and wrap with $q . So the response still will be promise.
And this is an example I use that might help you to understand what I'm meaning:
app.service('apiService', ['$http', '$q', '$rootScope',
function($http, $q, $rootScope) {
var request = function(method, data) {
var deferred = $q.defer();
var configHttp = {
method: 'POST',
url: config.api + '/' + method
};
if (data !== undefined) {
configHttp.data = data;
}
$http(configHttp).success(function(data, status, headers) {
if (data.error === undefined) {
deferred.resolve(data);
} else {
deferred.reject(data);
}
}).error(function(data, status, headers) {
deferred.reject(data);
});
return deferred.promise;
}
return {
getItem: function() {
return request('get_item');
},
getItemByParams: function(id) {
return request('get_item_by_params', {id: id});
}
};
}
]);

AngularJS - Controller gets the data returned from Service (MVC Web API call) as undefined

I am new to AngularJS & working on a sample. In my sample app I have an MVC Web api (which returns some data from db) & it will be called from the Angular Services and returns the data to the Controller. The issue is I am getting the data in my Services success method properly but in my controller it always shows undefined & nothing is displayed in the view. Please see the code below:
My Controller code:
app.controller('CustomerController', function ($scope, customerService) {
//Perform the initialization
init();
function init() {
$scope.customers= customerService.getCustomers();
}
});
My Services code:
app.service('customerService', function ($http){
this.getCustomers = function () {
$http({
method: 'GET',
url: 'api/customer'
}).
success(function (data, status, headers, config) {
return data;
}).
error(function (data, status) {
console.log("Request Failed");
});
}
});
Please help me to fix this issue.
That's because your service defines the function getCustomers but the method itself doesn't actually return anything, it just makes an http call.
You need to provide a callback function in the form of something like
$http.get('/api/customer').success(successCallback);
and then have the callback return or set the data to your controller. To do it that way the callback would probably have to come from the controller itself, though.
or better yet, you could use a promise to handle the return when it comes back.
The promise could look something like
app.service('customerService', function ($http, $q){
this.getCustomers = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'api/customer'
}).
success(function (data, status, headers, config) {
deferred.resolve(data)
}).
error(function (data, status) {
deferred.reject(data);
});
return deferred;
}
});
Your problem is in your service implementation. You cannot simply return data since that is in the asynchronous success callback.
Instead you might return a promise and then handle that in your controller:
app.service('customerService', function ($http, $q){
this.getCustomers = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'api/customer'
})
.success(function (data, status, headers, config) {
// any required additional processing here
q.resolve(data);
})
.error(function (data, status) {
q.reject(data);
});
return deferred.promise;
}
});
Of course if you don't require the additional processing, you can also just return the result of the $http call (which is also a promise).
Then in your controller:
app.controller('CustomerController', function ($scope, customerService) {
//Perform the initialization
init();
function init() {
customerService.getCustomers()
.then(function(data) {
$scope.customers= data;
}, function(error) {
// error handling here
});
}
});
VERY late answer, but, Angular's $http methods return promises, so there's no need for wrapping everything into promise form with $q. So, you can just:
app.service('CustomerService', function ($http) {
this.getCustomers = function () {
return $http.get('/api/customer');
};
});
and then call the .success() or .error() shortcut methods in your client controller.
If you want to take it a step further and have a fully-fledged RESTful CustomerService without having to write this boilerplate, I'd recommend the restangular library, which makes all sorts of methods available to you - assuming of course your backend responds to HTTP verbs in the "standard fashion".
Then you could just do this:
app.service('CustomerService', function (Restangular) {
return Restangular.service('api/customer');
});
and call the methods Restangular makes available to you.
I use this for communication between Angular Web Data Service and Web Api Controller.
.factory('lookUpLedgerListByGLCode', function ($resource) {
return $resource(webApiBaseUrl + 'getILedgerListByGLCode', {}, {
query: { method: 'GET', isArray: true }
});
})
OR
.factory('bankList', function ($resource) {
return $resource(webApiBaseUrl + 'getBanklist_p', {}, {
post: {
method: 'POST', isArray: false,
headers: { 'Content-Type': 'application/json' }
}
});
})

Proper way to set up angularjs factory with cached data

I'm just starting out with Angular.js and I'm trying to figure out how to set up a factory that will show cached data and replace it with data retrieved from a REST service once it is received.
To test this out, I'm just hard-coding the "cached" data. Once the data is received, I want the $scope.directory variable to be updated with the latest data received from the server. I can either get it
Here's my factory code:
app.factory('directoryFactory', function ($http) {
var factory = {};
factory.directory = [{name: "Test", ext: "123"},{name: 'Bob', ext: "234"}];
init();
function init() {
$http({
method: 'GET',
url: '{restapiURL}'
})
.success(function (data, status, headers, config) {
factory.directory=data;
})
.error(function (data, status, headers, config) {
console.log('directory fail');
});
}
}
My Controller has the following code:
$scope.directory = directoryFactory.directory;
In my view, I use ng-repeat to list out all the people and their extensions.
I'd like the view to be updated once the data is received. What's the correct way to watch for factory data changes?
Your $scope.directory is promise that contains 2 handlers on success and on failure. Since $http is asynchronous, you don't know when response should come but "promise" will notify you about in case if you use then()
Here is example of POST but its the same flow:
factory:
myModule.factory('ajax_post', ['$http', function(_http) {
var path = 'src/php/data.ajax.php';
return{
init: function(jsonData){
var _promise= _http.post(path,
jsonData
,{
headers: {
'SOAPActions': 'http://schemas.microsoft.com/sharepoint/soap/UpdateListItems'
}
}
);
return _promise;
}
}
}]);
In controller:
var _promise= ajax_post.init(jsonData);
_promise.then(function (result) {
//do something with your result
},
function (error) {
alert(error.message);
}
);

Resources