I have a angularJS application with an api service defined as follows:
(function ()
{
'use strict';
angular
.module('myApp')
.factory('api', apiService);
/** #ngInject */
function apiService($resource)
{
var api = {};
// Base Url
api.baseUrl = 'http://localhost:37243/';
api.Auth = $resource(api.baseUrl + 'auth/:verb', {}, {
login: {
method: "POST",
params: {
verb: 'credentials'
}
},
logout: {
method: "GET",
params: { verb: 'logout' }
},
getSession: {
method: "GET",
params: { verb: 'session' }
}
});
return api;
}
})();
and I am executing the login method from an Auth service like this:
authService.login = function (user, success, error) {
var apiAuth = new api.Auth();
apiAuth.$login(user).then(
function (response) {
var loginData = response;
authService.getSession();
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
success(loginData);
}, function (response) {
$rootScope.$broadcast(AUTH_EVENTS.loginFailed);
error(response);
});
};
The api call is working but it is passing the payload in the query string rather than a data payload. I guess I have $resource configured incorrectly but cannot work out why.
What is being sent:
http://localhost:37243/auth/credentials?password=Password1&username=admin
What I want to be sent:
POST http://localhost:37243/auth/credentials
{password: 'Password1', username: 'admin'}
Any ideas?
I've worked out the problem...
The reason is because I'm instantiating the resource object Auth and then executing the method.
From the ngResource documentation, the method signatures for "non-GET" methods (like mine) are:
non-GET "class" actions: Resource.action([parameters], postData,
[success], [error])
non-GET instance actions: instance.$action([parameters], [success], [error])
So I was running under the second circumstance where there is no postData parameter.
Changing my code to not instantiate the object, as follows, worked:
//the login function
authService.login = function(user, success, error) {
api.Auth.login(null, user).then(
function(response) {
var loginData = response;
authService.getSession();
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
success(loginData);
}, function(response) {
$rootScope.$broadcast(AUTH_EVENTS.loginFailed);
error(response);
});
};
For more info see this SO answer (up-voted)
Related
I'm calling a method inside my Web Api 2 controller, passing in a model called login which consists of EmailAddress and Password. However it hits the method but the model passed in is always null...
My call from AngularJs function :
var login = { "EmailAddress": emailAddress, "Password": password };
$http.post("/api/Login/", { headers: { 'RequestVerificationToken': $scope.antiForgeryToken } }, login).success(function () {
alert('succes');
}).error(function () {
alert('Unable to login at present, please try again later');
});
My method:
[ValidateAntiForgeryToken]
public void Post([FromBody]Login login)
{
var t = login.EmailAddress;
}
I think its something to do with how I've structure my actual Angular $http.post method but again I'm not sure, can anyone suggest would could potentially be wrong with it?
Can you use ajax and Razor?
var login = { "EmailAddress": emailAddress, "Password": password };
$.ajax({
url: "#Url.Action("api/login", "Controller", login)",
type: "GET",
data: {},
success: fCheckBoxes
});
Why cannot add the token to every request by configuring your app.js
// Set header for every request
app.factory('httpRequestInterceptor', function ($localStorage) {
return {
request: function (config) {
if ($localStorage.token != null)
config.headers['myAppToken'] = $localStorage.token;
return config;
}
};
});
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});
I define a factory for "Dashboard":
myApp.factory('Dashboard', ['$resource', function($resource) {
return $resource("/dashboards/:id", { id: "#id" },
{
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'show': { method: 'GET', isArray: false },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
}
);
}]);
In order to update a dashboard I need to use the class method:
$scope.dashboard = Dashboard.get({ id: 1234 });
Dashboard.update({ id: $scope.dashboard.id }, $scope.dashboard);
Instead is there a way I can call it as an instance method of a particular dashboard?
$scope.dashboard = Dashboard.get({id: 1234 });
$scope.dashboard.update();
Check out the docs.
About halfway down:
The action methods on the class object or instance object can be invoked with the following parameters:
HTTP GET "class" actions: Resource.action([parameters], [success], [error])
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
non-GET instance actions: instance.$action([parameters], [success], [error])
And an example from their page:
var User = $resource('/user/:userId', {userId:'#id'});
var user = User.get({userId:123}, function() {
user.abc = true;
user.$save();
});
I have a need to transform response from service on each get, save, update. I've created a resource and added a transformer that gets executed, but the structure of object being returned is not the same as when I don't use transformer. Here I am talking about the structure of the response, not the object I am transforming.
Here is my resource:
angular.module('app')
.factory('Insureds', ['$resource', 'config', function ($resource, config) {
function transform(response) {
var insured = response.data.insured;
return response;
}
var memberServicesHostName = config.memberServicesHostName;
return $resource(memberServicesHostName + '/insureds/:insuredId', null,
{
'get': {
method: 'GET', 'withCredentials': true, interceptor:
{
response: function (response) { return transform(response).data; }
}
},
'update': { method: 'PUT', 'withCredentials': true },
'save': { method: 'POST', 'withCredentials': true }
});
}]);
When I don't use transformer "insured" is on the first level when the promise gets resolved it resolves as an instance of insured object. But with transformer there is wrapper object, that contains insured and responseStatus properties. It probably has to do with what I am returning from the "reponse" in the interceptor. What should one return, original response, like I am doing, or response.data, or response.resource.insured? I am confused...
The default response interceptor is like this:
function defaultResponseInterceptor(response) {
return response.resource;
}
Therefore, if you would like to preserve the default behaviour, you have to return response.resource instead of response.data:
return $resource(memberServicesHostName + '/insureds/:insuredId', null, {
get: {
method: 'GET',
withCredentials: true,
interceptor: {
response: function (response) {
return transform(response).resource;
}
}
},
...
Hope this helps.
I am trying to build my first Angular $resource to give my application access to CRUD operations, but for some reason the actions being configured for the resource are not defined when I try to execute a query.
Here is my controller logic:
app.controller('MainCtrl', function ($scope, $http, $resource) {
var Alert = $resource('/WebApi/Alert/:type/:id',
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
$scope.systemUpdate = function (alert) {
var data = Alert.systemUpdate({ type: alert.Status, id: alert.AlertId }); // THIS LINE FAILS
console.log(data);
}
I get an error saying that Alert.systemUpdate is not defined. Am I doing something wrong here when configuring my $resource?
Change the definition of your Alert to
var Alert = $resource('/WebApi/Alert/:type/:id',
{},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
As mentionned in the documentation of $resource, the order of the parameters is the following:
1) Url
2) The default value of the parameters of the url, since you don't have any default value, you must provide an empty object
3) The actions (systemUpdate & autoArchive here)
how to make Generic method for rest call in angularjs ?
i have tried for single request, it's working fine
UIAppRoute.controller('test', ['$scope', 'checkStatus', function($scope, checkStatus) {
$scope.data = {};
checkStatus.query(function(response) {
$scope.data.resp = response;
});
}])
UIAppResource.factory('checkStatus', function($resource){
return $resource(baseURL + 'status', {}, {'query': {method: 'GET', isArray: false}})
})
I want to make this as generic for all the request
Please share any sample,.. thanks in advance
I'm using something like this :
.factory('factoryResource', ['$resource', 'CONF',
function($resource, CONF) {
return {
get: function(endPoint, method) {
var resource = $resource(CONF.baseUrl + endPoint, {}, {
get: {
method: method || 'GET'
}
});
return resource.get().$promise;
}
};
}
])
called by :
factoryResource.get(CONF.testEndPoint, "POST"); // make a POST and return a promise and a data object
factoryResource.get(CONF.testEndPoint, "GET"); // make a GETand return a promise and a data object
factoryResource.get(CONF.testEndPoint); // make a GETand return a promise and a data object
with a config file having :
angular.module('app.constant', [])
.constant('CONF', {
baseUrl: 'http://localhost:8787',
testEndPoint: '/api/test'
});