Getting Data From Service - javascript

Here is my controller and service:
var app = angular.module('myApp', ['ui.bootstrap']);
app.service("BrandService", ['$http', function($http){
this.reloadlist = function(){
var list;
$http.get('/admin.brands/getJSONDataOfSearch').
success(function(data, status, headers, config) {
list = data;
}).
error(function(data, status, headers, config) {
});
return list;
};
}]);
app.controller('BrandsCtrl', ['$scope','$http','$controller','BrandService', function($scope, $http, $controller, BrandService) {
$scope.brands = BrandService.reloadlist();
angular.extend(this, $controller("BrandCtrl", {$scope: $scope}));
}]);
I searched for this issue and tried answers of questions but I couldn't get solution. I am new at angular so can you explain with details; why I couldn't get the data from service to controller this way ?

The return used for data is for the callback of your function.
You must use the promise returned by $http like this.
In your service return the promise :
return $http.get('/admin.brands/getJSONDataOfSearch').
success(function(data, status, headers, config) {
return data;
}).
error(function(data, status, headers, config) {
});
Use then() on the promise in your controller :
BrandService.reloadlist()
.then(function (data){
$scope.brands = data;
});

It's not angular, it's the Javascript. The function you put in this.reloadlist does not return any value. It has no return at all, so the value returned will be undefined. The success handler does return something, but it will be run long after reloadlist finished working.

Besides what #fdreger already pointed out (missing return value), $http.get(...) is an async method. The return value is a promise not the actual value.
In order to access the value you need to return it from reloadlist like this:
this.reloadList = function() {
return $http.get('/admin.brands/getJSONDataOfSearch');
// you need to handle the promise in here. You could add a error handling here later by catching stuff...
}
and in the controller you can add it to the $scope like this:
BrandService
.reloadlist()
.then(function(res) {
$scope.brands = res.data;
});
The callback passed to then() is called as soon as the HTTP request has successfully completed, this makes the call asynchronous.
Besides the angular documentation for promises the article on MDN is a good read too.

Related

Calling another function in ng-repeat

I am using AngularJs 1.5 RC build.
I have a view wherein I am using ng-repeat to iterate over a collection , like so
<tr ng-repeat="user in users">
<td>{{user.JobID}}</td>
<td>{{getManager(user.userID)}}</td>
<td>{{user.StatusDesc}}</td>
<td>{{user.StartedAt}}</td>
</tr>
The idea here is to use the getManager function to get the name of the manager for each and every user in the users collection.
As an aside , I have to use this approach since the API is not returning me all the information.
This is how the getManager function looks like now.
$scope.getManager = function($id) {
return "John Doe";
}
The entire controller looks as follows
var app = angular.module('userapp', ['ui.bootstrap']);
app.controller('MainController', ['$scope','$http', function($scope, $http) {
$scope.getUsers = function() {
$http.get("http://localhost/getUsers").
success(function(data, status, headers, config) {
$scope.users = data.resource;
}).
error(function(data, status, headers, config) {
// log error
console.error("An error as encountered. Error follows:");
console.error(data);
});
}
$scope.getManager= function($id) {
return "John Doe";
}
}]);
So in my page view, I am getting "John Doe" as a manager for all my users.
Problem
The problem begins whenever I try to get the real manager for a user. So if i replace my dummy getManager with the following function
$scope.getManager = function($id) {
$http.get("http://localhost/user/manager/"+$id).
success(function(data, status, headers, config) {
return (data.resource[0].ManagerName);
}).
error(function(data, status, headers, config) {
// log error
console.error("An error as encountered. Error follows:");
console.error(data);
});
}
AngularJs starts complaining and fails with the following
https://docs.angularjs.org/error/$rootScope/infdig?p0=10&p1=%5B%5D
Can you please let me know what might be happening here.
Please note , I am an Angular noob, hence your patience will be well appreciated.
Thanks
You should call ajax in that way inside {{}} interpolation. It will get called on each digest cycle and will throw $rootScope/infdig error.
So I'd suggest you to call the getManager method as soon as you retrieve a data from server. Then after getting data from a server you need to call getManager method just by passing UserId(look I change getManager implementation to return managerName by returning data). After getting managerName you need to bind that manager name to user object & use {{user.ManagerName}} on the HTML.
Markup
<tr ng-repeat="user in users">
<td>{{user.JobID}}</td>
<td>{{user.managerName}}</td>
<td>{{user.StatusDesc}}</td>
<td>{{user.StartedAt}}</td>
</tr>
Code
$scope.getUsers = function() {
$http.get("http://localhost/getUsers")
.success(function(data, status, headers, config) {
$scope.users = data.resource;
angular.forEach($scope.users, function(user){
(function(u){
$scope.getManager(u.UserID).then(function(name){
u.ManagerName = data;
})
})(user);
})
})
};
$scope.getManager = function($id) {
return $http.get("http://localhost/user/manager/"+$id).
then(function(response) {
var data = response.data;
return (data.resource[0].ManagerName);
},function(error) {
console.error("An error as encountered. Error follows:");
});
};
Side Note
Don't use .success & .error function on $http calls as they are
deprecated.
This is a really bad practice. If you have N users, you will send N queries to fetch every data. You should return this data in http://localhost/getUsers response.
You can try:
$scope.getManager = function($id) {
return $http.get("http://localhost/user/manager/"+$id)
...
}

AngularJS $http result with promise

I am new in angular $q service.I'm using $http with angular $q service for implementing asynchronous requests. Here in below is my codes which I can't get the result of backend api. (json)
Services.js :
.service('httpService', function($q, $http, $timeout) {
var asyncRequest = function(url) {
return $http.get(url)
.then(function(response) {
//res is the index of an array in php, which will be encoded.
return response.res;
}, function(response) {
// something went wrong
return $q.reject(response.res);
});
};
return {
asyncRequest : asyncRequest
};
});
Controller.js :
var result = httpService.test(url)
.then(function(data) {
// Line below gives me "undefined"
console.log(data);
}, function(error) {
alert("Error...!");
});
The mentioned line, gives me undefined. (Of course, I can write console.log(data) in main function, But it's not a good practice, because I want to return result to controller)
About my implementation of $q service, is there any easier way?
Any idea would be greatly appreciated.
You should not use $q in this instance, as $http already returns a promise. Using to 2 together in inefficient. ($q is of use if you are using a non-angular async function, such as a Geo lookup).
Services.js :
.service('httpService', function($http, $timeout) {
var asyncRequest = function(url) {
return $http.get(url)
};
return {
asyncRequest : asyncRequest
};
});
Controller.js :
var result = httpService.asyncRequest(url)
.then(function(res) {
console.log(res.data);
}, function(error) {
alert("Error...!");
});
First thing is that you are using factory style instead of service. service is just a function where methods are defined on this reference .
I think you don't need to use .then in service just return the promise returned by $http
app.service('httpService', function($q, $http, $timeout) {
this.asyncRequest = function(url) {
return $http.get(url);
};
});
And in controller
var result = httpService.test(url)
.then(function(res) {
// Line below gives me "undefined"
console.log(res.data);
}, function(error) {
alert("Error...!");
});
I think you are using the syntax for at factory on your service.
.service('httpService', function($q, $http, $timeout) {
this.asyncRequest = function(url) {};
});
or
.factory('httpService', function($q, $http, $timeout) {
return {asyncRequest: function(url) {}};
});
The response is already rejected in the mentioned line. You don't need to reject anything else. So you don't need to $q.
First you already return a promise. You can handle it in the controller with adding success() and error() delegates of the $http promise.
Second, this is async operation. And you can't return a response from the success callback like jQuery.ajax(). This is not synch call, this is asynch call and you have to use callbacks. Your mistake is here. Just return promise and handle it in controller when the response will has been resolved or rejected.
So your controller code can be like this:
httpService.asyncRequest({
...
}).success(function(successfulResponse) {
...
}).error(function(failedResponse) {
...
});
.service('httpService', function($q, $http, $timeout) {
var asyncRequest = function(url) {
var defer = $q.defer();
return $http.get(url)
.then(function(response) {
//res is the index of an array in php, which will be encoded.
defer.resolve(response);
}, function(response) {
// something went wrong
defer.reject(response.res);
});
return defer.promise;
};
return {
asyncRequest : asyncRequest
};
});
you should return promise from your object like this

proper way to call http (RESTFUL WebAPI) in angularjs

I have following controller code
module.registerController('DemoCtrl', function ($scope, myFactory) {
myFactory.get(function (data) {
console.log(data); /// data is always undefined
});
});
and following the factory which is calling restful webapi
module.registerFactory('myFactory', ['$http',
function ($http) {
function get(callback) {
$http.get('mywebapiurl')
.success(function (response) {
//debugger; data comes back from server
callback(response);
}).error(function (response, status, headers, config) {
callback(response);
});
}
return {
get: get
}
}]);
The factory is calling webapi service and does gets the data back. However in controller the data doesnt get returned.
Am I missing something obvious here? Also not sure if this is the best way to call webservice in angularjs in controller using factory. Any inputs are most welcome.
Thanks,
You want to return a promise instead of passing a callback. As $http.get already returns a promise, you can just return that, or a derived promise that returns the response data directly. By the way, your factory looks like it should be a service instead:
angular.moudule('yourApp')
.service('myService', ['$http', myService]);
function myService($http) {
this.get = function(url) {
return $http.get(url)
.then(function transformData(response){
return response.data;
}).catch(function onError(rejectionResponse){
//Whatever you want to do here
});
}
}
This way myService.get will return a promise you can .then(), .catch() and .finally() on what you want, staying in the frameworks coding style. For example:
var squirrels = [];
myService.get('http://squirrelshop.com/api/squirrels')
.then(function(squirrelsData){
console.log('Got the squirrels!');
squirrels = squirrelsData;
}).catch(function(rejection){
console.warn('Couldnt fetch squirrels. Reason: ' + rejection);
});
controller code
module.registerController('DemoCtrl', function ($scope, myFactory) {
myFactory.get("url").then(function(d) {
console.log(d.data);
}
});
});
factory which is calling restful webapi
module.registerFactory('myFactory', ['$http',
function ($http) {
var apiFactory = {
get:function(url){
return $http.get(url);
}
}
return apiFactory;
}]);
Success and failure in factory
module.registerFactory('myFactory', ['$http',
function ($http) {
var apiFactory = {
get:function(url){
return $http.get(url).then(function(response){
// success
return responce.data;
},function(error){
//failure
return error;
};
}
}
return apiFactory;
}]);

How to use a service with Http request in Angular JS

I'm using AngularJS to build my web application, I've been always using controllers to make HTTP request, which makes things easier and clear for me.
But for a better code structure, and better execution for my application, I wanted to use services instead of controllers to use the web service.
I tried to make :
var app = angular.module('ofcservices', []);
app.factory('news', ['$http', function ($http) {
var news={};
news.getnews= function () {
return $http.get('http://int.footballclub.orange.com/ofc/news?offset=0&limit=5');
};
return news;
}]);
and the code of the controller :
.controller('news', function($scope, ofcservices) {
$scope.news = ofcservices.getnews();
})
Everything seems to be right ?
ofcservices.getnews() is a promise You need manage with the function sucess and error
ofcservices.getnews().
success(function(data) {
$scope.news=data
}).
error(function(data, status, headers, config) {
//show a error
});
As weel change app.factory('news' to app.factory('newsFactory' and call it in controller('news', function($scope, newsFactory) {
You can get more data about promise in the angular documentation
The concept is more or less right, but you should use the callback functions to handle the $http response correctly.
But your controller and service have the same name news, which is BAD :-) and you need to inject the newsService and not the module name.
.controller('newsController', function($scope, newsService) {
newsService.getnews().then(
function(newsData) {
$scope.newsData = newsData
},
function optionalErrorhandler() {});
})
angular
.module('MyApp', [])
.controller('MyController', MyController)
.factory('MyService', MyService);
MyController.$inject = ['$scope','MyService'];
MyService.$inject = ['$http'];
function MyService($http){
var service = {
var myServiceFunction : function(){
$http({
// your http request on success return the data.
}).success(function(data)){
return data;
});
}
};
return service;
}
function MyController($scope, MyService){
MyService.myServiceFunction(); //Call service from the controller.
}

Angular.js service factory $http.get not calling my service

I am trying to get data in service factory. Nothings happen.It executed code. But nothings happened. Dont know why?
Here is my service code:
'use strict';
app.factory('accountService', function($http, $location, $rootScope) {
return {
accounts: function() {
$http.get('http://localhost:29045/AccountOperation.svc/GetAccounts').success(function(data, status, headers, config) {
console.log(status);
var $promise = data;
console.log(data);
}).error(function(data, status, headers, config) {
});
}
}
});
Here is my controller(calling factory from here):
'use strict';
app.controller('accountController', function($scope, accountService, $rootScope) {
$scope.accounts = function() {
accountService.accounts();
}
});
Also i didnt get error.
On your account function you are not creating a promise or returning anything. Try:
app.factory('accountService', function($http, $location, $rootScope) {
return {
accounts: function() {
return $http.get('http://localhost:29045/AccountOperation.svc/GetAccounts');
}
}
});
This returns the promise and you can handle it anywhere you call the acccount function or you could create a promise inside the function and return it. then inside the success or error methods resolve or reject it.
I think you have to return your promise from the factory. Look at the following post under "Promises and Services"
http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/

Categories

Resources