Angular - How to Project $http Response - angularjs

I want to project the result of my $http call into another model in order to make the projection global to the service call.
In other words, the result i get from my http/api call is not using the exact model i want.
How do i do this projection within my service class?
angular.module('openart')
.factory('BritishLibraryApi', ['$http', function ($http) {
return {
getPage:function(page){
return $http({method:"GET",url:'/api/british-library/'+page})
.success(function(data){
//would like to do something here like
return data.results.map(function(i){
//project i into another model here
return {
};
});
});
}
};
}]);

If you create your own promise and resolve to your mapped data
angular.module('openart')
.factory('BritishLibraryApi', ['$http','$q', function ($http,$q) {
return {
getPage:function(page){
var defer=$q.defer();
$http({method:"GET",url:'/api/british-library/'+page})
.success(function(data){
//would like to do something here like
defer.resolve(data.results.map(function(i){
//project i into another model here
return {
};
}));
});
return defer.promise;
}
};
}]);

Related

How to pass object to angularjs controller using MVC controller Action

I want to send object to angularjs Controller using MVC Controller Action is it possible?
suppose
public ActionResult Dashboard()
{
return View();
}
I want to pass object to app.js how to do this
Your question is a bit vague , you need to be more specific on what exactly you are trying to do.
Generally , this his how you would get data in Angular from the MVC application.
In Case of MVC/WebAPI , you should use actions to return JSON result back to the angular service which can then be processed by angular.
Example below :
app.factory('myService', function($http) {
var myService = {
GetData: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get('<ActionURL>').then(function (response) {
// The then function here is an opportunity to modify the response
console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
// Call the async method and then do stuff with what is returned inside our own then function
myService.GetData().then(function(d) {
$scope.data = d;
});
});
After this services is called from the MainCtrl , angular will have the data from the MVC action available in its $scope.data variable.

How to use 'Controller as' with $http in Angular

I'm trying to load some data through $http to prefill a profile form. Unfortunately all the examples I find online use the $scope-approach rather than 'Controller as'-approach (which I'm using to make future transition to Angular 2 easier). These examples assign the $http response to the '$scope' variable, which is not possible when using 'this'.
After a lot of fiddling I managed to get it to work by adding a temp variable
var temp = this;
to which I can assign the $http response when it successfully returns.
angular.module('angularUserApp')
.factory('ajax',['$http',function($http){
return {
getProfile: function(){
return $http.get('/ajax/user/profile')
.then(function(response){
return response.data.data.profile;
});
}
}
}])
.controller('userProfileCtrl', ['ajax', function (ajax) {
var temp = this;
ajax.getProfile().then(function(response){
temp.profile = response;
});
}]);
Is there a more elegant approach?
Your approach for using controllerAs is correct. Just a few advices though, better alias the this to a variable vm, which stands for viewModel instead of temp, and name your service semantically: userService instead of ajax:
angular.module('angularUserApp')
.factory('userService', function ($http){
return {
getProfile: function () {
return $http.get('/ajax/user/profile')
.then(function (response){
return response.data.profile;
});
}
}
})
.controller('userProfileCtrl', function (userService) {
var vm = this;
userService.getProfile().then(function (response) {
vm.profile = response;
});
});
One of the design ideas of angular is that you can use $scope. Simply inject $scope into your controller, like you did with your ajax service and set the profile response to the $scope variable ($scope.profile = response;).
As a result you would get something like:
angular.module('angularUserApp')
.factory('ajax',['$http',function($http){
return {
getProfile: function(){
return $http.get('/ajax/user/profile')
.then(function(response){
return response.data.data.profile;
});
}
}
}])
.controller('userProfileCtrl', ['ajax', '$scope', function (ajax, $scope) {
ajax.getProfile().then(function(response){
$scope.profile = response;
});
}]);
// In your template
<div ng-controller="userProfileCtrl">
<div ng-bind="profile.name"></div>
</div>

AngularJS hide promises while using $resource

I have a simple RESTful service like the following:
services.factory('UserService', ['$resource, function() {
return $resource('...');
}]);
This way I have to invoke like this:
UserService.get({id: userId}, function(response) {
// do something.
});
I wanted to be able to do something like this:
UserService.get(userId).then(function(response) {
// do something with data
});
Is it possible? I am struggling with this and end up always having to use $promise.then() in my controllers. I wanted to "hide" that $promise in my RESTful service.
$resource purposely exposes the promise through ... well ... $promise, so you can use the UserService to abstract this:
services.factory("UserService", ["$resource", function ($resource) {
var userService = $resource("...");
return {
get: function (id) {
return userService.get({id: id}).$promise;
}
}
});
According to Todd Motto you could encapsulate your service somewhat like this :
"We create an Object with the same name inside the function. This can aid documentation as well for comment-generated docs."
function AnotherService () {
var AnotherService = {};
AnotherService.someValue = '';
AnotherService.someMethod = function (idParam) {
return $resource(apiUrl + ":action/:id", {}, {
get: {method: 'GET', params: {id:idParam, action: 'get'}
};
return AnotherService;
}
angular.module('app')
.factory('AnotherService', AnotherService);

update a service variable within an $http callback

I'm using a service to make user data available to various controllers in my Angular app. I'm stuck trying to figure out how to use the $http service to update a variable local to the service (in my case "this.users"). I've tried with and without promises. The server is responding correctly.
I've read several excellent articles for how to use $http within a service to update the scope of a controller. The best being this one: http://sravi-kiran.blogspot.com/2013/03/MovingAjaxCallsToACustomServiceInAngularJS.html. That does not help me though because it negates the benefits of using a service. Mainly, modifying the scope in one controller does not modify throughout the rest of the app.
Here is what I have thus far.
app.service('UserService', ['$http', function($http) {
this.users = [];
this.load = function() {
var promise = $http.get('users.json')
.success(function(data){
// this.users is undefined here
console.log(this.users);
}
};
promise.then(function() {
// this.users is undefined here
console.log('this.users');
});
}]);
Any help is greatly appreciated. Thank you.
Try using
var users = [];
rather than
this.users = [];
and see what
console.log(users);
outputs in each of those cases.
Your service is oddly defined, but if you have a return in it you can access it from any controller:
app.service('UserService', ['$http', function($http) {
var users = [];
this.load = function() {
var promise = $http.get('users.json')
.success(function(data){
// this.users is undefined here
console.log(users);
users = data.data;
}
};
return {
getUsers: function(){
return users;
}
}
}]);
so in your controller, you can use:
var myUsers = UserService.getUsers();
UPDATE to use a service correctly here, your service should return a promise and the promise should be accessed in the controller: Here's an example from another answer I gave
// your service should return a promise
app.service('PickerService', [$http', function($http) {
return {
getFiles: function(){
return $http.get('files.json'); // this returns a promise, the promise is not executed here
}
}
}]);
then in your controller do this:
PickerService.getFiles().then(function(returnValues){ // the promise is executed here as the return values are here
$scope.myDirectiveData = returnValues.data;
});
this does not have scope anymore where you are trying to use it do this instead:
app.service('UserService', [$http', function($http) {
var users = [];
this.load = function() {
var promise = $http.get('users.json')
.success(function(data){
console.log(users);
}
};
promise.then(function() {
console.log(users);
});
}]);
all local variables to a service should just be vars if you assign them to this as a property than they will be included every time the service is injected into a controller which is bad practice.
I think what your asking for is a solution along the lines of defining your service like this:
angular.module('app')
.service('User', function($http, $q) {
var users = null;
var deferred = $q.defer()
return {
getUsers: function() {
if(users) {
deferred.resolve(users);
} else {
$http.get('users.json');
.success(function(result) {
deferred.resolve(result);
})
.error(function(error) {
deferred.reject(error);
});
}
return deferred.promise;
}
};
});
Then in one Each controller you would have to do this:
angular.module('app')
.controller('ACtrl', function($scope, User) {
User.getUsers().then(function(users) {
// Same object that's in BCtrl
$scope.users = users;
});
});
angular.module('app')
.controller('BCtrl', function($scope, User) {
User.getUsers().then(function(users) {
// Same object that's in ACtrl
$scope.users = users;
});
});
NOTE: Because the deferred.promise the same promise passed to all controllers, executing deferred.resolve(users) in the future will cause all then success callbacks in each of your controllers to be called essentially overwriting the old users list.
All operations on the list will be noticed in all controllers because the users array is a shared object at that point. This will only handle updates to the user list/each individual user on the client side of your application. If you want to persist changes to the server, you're going to have to add other $http methods to your service to handle CRUD operations on a user. This can generally be tricky and I highly advise that you check out ngResource, which takes care of basic RESTful operations

AngularJS passing JSON object to directive

I'm getting json file from REST server using factory:
.factory('chartData', function($http){
return {
get: function() {
return $http.get('http://').then(function(result) {
return result.data;
});
}
}
})
Now how can i pass this to directive which i'm using to make chart?
I suppose i would need to use controller?
Promises do not work this way.
Try this:
.factory('chartData', function($http){
return {
get: function() {
return $http.get('http://');
}
}
});
and in your directive:
chartData.get().then(function(result) {
$scope.chartData = result.data;
initChart();
});
This video can be helpfull: angularjs-promises

Resources