Angularjs - $resource as a service, issue with multiple urls - angularjs

I have this service :
(function() {
'use strict';
angular
.module('myApp')
.factory('Consultant', Consultant);
Consultant.$inject = ['$resource', 'DateUtils'];
function Consultant ($resource, DateUtils) {
var resourceUrl = 'api/consultants/:id';
return $resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
},
'update': {
method: 'PUT',
transformRequest: function (data) {
return angular.toJson(data);
},
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
},
'save': {
method: 'POST',
transformRequest: function (data) {
return angular.toJson(data);
},
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
}
})();
What if I want to add the url api/consultantscustom/:id (with its query/get/update methods) to this service?
As it seems that this file can contain only one factory, is there a way to do that or do I need to create another file with a new factory?

Maybe I am totally misunderstanding what you are asking, but you can have as many factories in one file as you like (or as seems useful):
(function() {
'use strict';
angular.module('myApp')
.factory('Consultant', Consultant)
.factory('Custom', Custom);
Consultant.$inject = ['$resource', 'DateUtils'];
Custom.$inject = ['$resource'];
function Consultant ($resource, DateUtils) {
var resourceUrl = 'api/consultants/:id';
...
}
function Custom ($resource) {
var resourceUrl = 'api/consultantscustom/:id';
...
}
Or, if you want to re-use the same factory to access different URLs, you could add methods to set the URL and then re-use the call to the generic resource.
function Consultant ($resource, DateUtils) {
function consultants () {
_call_resource('api/consultants/:id');
}
function custom () {
_call_resource('api/consultantscustom/:id');
}
function _call_resource (resourceUrl) {
return $resource(resourceUrl, {}, {
...
}
}
this.consultants = consultants;
this.custom = custom;
return this;
}

Related

How to instantiate angular service with multiple resources?

I have an angular service based on meanjs for rents. Originally it looked like this:
(function () {
'use strict';
angular
.module('rents.services')
.factory('RentsService', RentsService);
RentsService.$inject = ['$resource', '$log'];
function RentsService($resource, $log) {
var Rent = $resource(
'/api/rents/:rentId',
{
rentId: '#_id'
},
{
update: {
method: 'PUT'
},
getByCarId:
{
method: 'POST',
params: {
rentId: 'bycar'
},
isArray: true,
hasBody: true,
requestType: 'json',
responseType: 'json'
}
}
);
angular.extend(Rent.prototype, {
createOrUpdate: function () {
var rent = this;
return createOrUpdate(rent);
}
});
return Rent;
// and all other function that are the same as down below
}());
Then I added a second resource
(function () {
'use strict';
angular
.module('rents.services')
.factory('RentsService', RentsService);
RentsService.$inject = ['$resource', '$log'];
function RentsService($resource, $log) {
var Rent =
{
basic: $resource(
'/api/rents/:rentId',
{
rentId: '#_id'
},
{
update: {
method: 'PUT'
},
getByCarId:
{
method: 'POST',
params: {
rentId: 'bycar'
},
isArray: true,
hasBody: true,
requestType: 'json',
responseType: 'json'
}
}
),
carUsageStats: $resource(
'/api/rents/car_usage'
)
};
angular.extend(Rent.basic.prototype, {
createOrUpdate: function () {
var rent = this;
return createOrUpdate(rent);
}
});
return Rent;
function createOrUpdate(rent) {
if (rent._id) {
return rent.$update(onSuccess, onError);
} else {
return rent.$save(onSuccess, onError);
}
// Handle successful response
function onSuccess(rent) {
// Any required internal processing from inside the service, goes here.
}
// Handle error response
function onError(errorResponse) {
var error = errorResponse.data;
// Handle error internally
handleError(error);
}
}
function handleError(error) {
// Log error
$log.error(error);
}
}
}());
Until I added second resource, this resolve function for creating new rent worked fine
newRent.$inject = ['RentsService'];
function newRent(RentsService) {
return new RentsService();
}
But when I added second resource (and had to address the one I want by using property name - cant use Rent.query() but Rent.basic.query()) instantiating new Rent no longer works. I added console log outputs around and code stops executing at line var rent = new RentsService(). Querying works fine. What is the correct way of making new object using service with multiple resources?

How do I delete a post using this with angularJS and express?

I have this code in my post.serv.js and in my controller I want to execute the function delete.
"use strict";
app.factory('JnttPost', function ($resource) {
var PostResource = $resource('/api/post/:_id', {
_id: "#id"
}, {
update: {
method: 'PUT',
isArray: false
}
}, {
delete: {
method: 'DELETE',
isArray: false
}
});
return PostResource;
});
I already know how to get and update a post, for example in my createpost.serv.js
"use stric";
app.factory('JnttCreatePost', function ($http, $q, JnttPost) {
return {
createPost: function (newPostData) {
var newPost = new JnttPost(newPostData);
var dfd = $q.defer();
newPost.$save().then(function () {
dfd.resolve();
}, function (response) {
dfd.reject(response.data.reason);
});
return dfd.promise;
}
};
});
and in my newpost.ctrl.js
"use strict";
app.controller('CtrlNewPost',
function ($scope, $location, JnttIdentity, JnttNotifier, JnttCreatePost) {
var email = ...;
$scope.newPost = function () {
var newPostData = {...};
JnttCreatePost.createPost(newPostData).then(function () {
JnttNotifier.notify('success', 'The post has been created');
$location.path('/');
}, function (reason) {
JnttNotifier.notify('error', reason);
});
};
});
I can't realize how to perform the delete request, I can do with a $http
In my new controller for do deletePost() function I have this:
$scope.deletePost = function () {
var pwd = JnttIdentity.currentUser.hashed_pwd;
var postidd = {
password: pwd,
id: $scope.post._id
};
var config = {
method: "DELETE",
url: '/api/post/',
data: postidd,
headers: {
"Content-Type": "application/json;charset=utf-8"
}
};
$http(config);
$location.path('/');
};
This actually already do this stuff but I want to do this without the $http like the create request, How I can do this? How do I can edit this code below for do the request?
createPost: function (newPostData) {
var newPost = new JnttPost(newPostData);
var dfd = $q.defer();
newPost.$save().then(function () {
dfd.resolve();
}, function (response) {
dfd.reject(response.data.reason);
});
return dfd.promise;
}
In my routes.js in express I have this route:
app.delete('/api/post/', posts.deletePost);
You can either call delete on the $resource class you create (JnttPost) or call $delete on a post that's returned from the $resource class.
The $resource class already has get/save/query/remove/delete functions included so you don't need to add the delete (save is create/POST, so you need to include update with PUT).
Here's a sample of using your $resource class to call delete:
angular.module('test', ['ngResource'])
.factory('JnttPost', function ($resource) {
var PostResource = $resource('/api/post/:_id', {
_id: "#id"
}, {
update: {
method: 'PUT',
isArray: false
}
});
return PostResource;
})
.run(function(JnttPost){
JnttPost.delete({id: 123123123});
});

Angularjs convert service from $resource to $http

How can I convert the following code service that uses $resource to use $http?
angular.module('myApp')
.factory('MyService', function ($resource) {
var url = "..";
return $resource("", {},
{
'servizio1': { method: "GET", url: basePath },
'servizio2': { method: "POST", url: url, data: {} },
'servizio3': { method: "POST", url: url, data: {} }
}
});
Thanks in advance.
First to your question, try something like:
angular.module('myApp')
.factory('MyService', function ($http) {
var url = "..";
var basePath = "...";
return {
servizio1: function(){ return $http.get(basePath); },
servizio2: function(data){ return $http.post(url, data); }
}
});
Call it with:
var returnValue = (new MyService()).servizio1.then(function(data){...})
But actually you could also use the $resource API and do something like:
angular.module('myApp')
.factory('MyService', function ($resource) {
var url = "..";
return $resource(url,{}, {
saveIt: {
method: 'POST',
params: {url: basePath}
}
});
adn call this with
MyService.get({}, function(data){...});
MyService.saveIt({}, postData, function(){success...}, function(){error...});
Check out AngularJS docs for more

How can I make a service dependent on another service value

Ok, so I have this service that is dependent on another service value that the user can change in the app interface. Something like this:
app.service('Applications', ['$resource', 'URL',
function ($resource, URL) {
var applicationsResource = $resource(URL + '/applications/:id', { id: '#id' }, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(body, header) {
var response = angular.fromJson(body);
return response.data.applications;
}
}
});
var applications = applicationsResource.query(function() {
applications.current = applications[0];
});
return applications;
}
]);
app.service('Users', ['$resource', 'URL', 'Applications',
function ($resource, URL, Applications) {
return $resource(URL + '/users/:id', { id: '#id' }, {
query: {
method: 'GET',
isArray: true,
headers: {
'User': Applications.current.username,
'Pass': Applications.current.password
},
transformResponse: function(body, header) {
var response = angular.fromJson(body);
return response.data.users;
}
}
});
}
]);
Example of working controller code:
app.controller('usersController', ['$scope', '$resource', 'URL', 'Applications',
function ($scope, $resource, URL, Applications) {
$scope.users = [];
$scope.reload = function() {
$scope.loading = true;
var usersResource = $resource(URL + '/users/:id', { id: '#id' }, {
query: {
method: 'GET',
isArray: true,
headers: {
'User': Applications.current.username,
'Pass': Applications.current.password
},
transformResponse: function(body, header) {
var response = angular.fromJson(body);
return response.data.users;
}
}
});
$scope.users = usersResource.query(function() {
$scope.loading = false;
});
/*
// after injecting Users, this is what I want to do, instead of what's above
$scope.users = Users.query(function() {
$scope.userTable.reload();
$scope.loading = false;
});
*/
};
$scope.$watch('Applications.current', function (newApplication, oldApplication, scope) {
if (newApplication && newApplication !== oldApplication) {
scope.reload();
}
});
}
]);
I want to replace that usersResource with my Users service, but that's where I'm stuck now.
The issue is that no matter what I do, the Applications.current on the Users service is always null. (I only make use of this service after making sure that Applications.current is not null on the controller)
If I move the resource directly to the controller, it works, but I want to move these away from the controllers.
Any tips on how to fix or improve this?
You should know that $resource is async and you call Users service before actually you got response from server and populated applications.current. This a reason why Applications.current is null into Users service.
In your case I would use Uses service into Applications:
app.service('Applications', ['$resource', 'URL', 'Users',
function ($resource, URL, Users) {
var applicationsResource = $resource(URL + '/applications/:id', { id: '#id' }, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(body, header) {
var response = angular.fromJson(body);
return response.data.applications;
}
}
});
var applications = applicationsResource.query(function() {
applications.current = applications[0];
// call the Users
Users.query(applications.current) /**/
return /* ... */;
});
return applications;
}
]);

How can I pass back a promise from a service in AngularJS?

I have some code in my controller that was directly calling $http to get data.
Now I would like to move this into a service. Here is what I have so far:
My service:
angular.module('adminApp', [])
.factory('TestAccount', function ($http) {
var TestAccount = {};
TestAccount.get = function (applicationId, callback) {
$http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
}).success(function (result) {
callback(result);
});
};
return TestAccount;
});
Inside the controller:
TestAccount.get(3, function (data) {
$scope.testAccounts = data;
})
How can I change this so rather than passing the result of success back it
passes back a promise that I can check to see if it succeeded or failed?
Make your service to return a promise and expose it to service clients. Change your service like so:
angular.module('adminApp', [])
.factory('TestAccount', function ($http) {
var TestAccount = {};
TestAccount.get = function (applicationId) {
return $http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
});
};
return TestAccount;
});
so in a controller you can do:
TestAccount.get(3).then(function(result) {
$scope.testAccounts = result.data;
}, function (result) {
//error callback here...
});

Resources