I have created a resource object:
factory('TextResource',
function($resource) {
return $resource(adminBaseUrl+'/texts/:type', {}, {
create: {method: 'POST', params: {type:'create'}, headers: {'Content-Type':'application/x-www-form-urlencoded'}},
update: {method: 'POST', params: {type:'update'}, headers: {'Content-Type':'application/x-www-form-urlencoded'}},
query: {method: 'GET', params: {type: 'list'}},
remove: {method: 'POST', params: {type: 'remove'}, headers: {'Content-Type':'application/x-www-form-urlencoded'}},
getText: {method: 'GET', params: {type: 'get', id:'#id'}}
});
}
)
And my controller is:
controller('EditText', ['$scope', '$location', '$routeParams', 'TextResource', 'HttpStatusMessage',
function($scope, $location, $routeParams, TextResource, HttpStatusMessage) {
$scope.alerts = [];
$scope.languages = [];
TextResource.getText(
{id: $routeParams.id},
function(data) {
$scope.languages = data.result;
},
function(error) {
var httpError = new HttpStatusMessage(error.status);
$scope.alerts.push({type:'error', msg:httpError.msg});
});
$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
}
$scope.submit = function() {
TextResource.update(
$scope.languages,
function(data) {
if( data.type == 'success' ) {
$location.path('texts');
} else {
$scope.alerts.push({type:data.type, msg:data.message});
}
},
function(error) {
var httpError = new HttpStatusMessage(error.status);
$scope.alerts.push({type:'error', msg:httpError.msg});
});
}
$scope.cancel = function() {
$location.path('texts');
}
}
])
The response i am getting from TextResource.getText request is:
{"result":[{"id":"3","value":"This is my first text<br>","key":"my_first_text","language_id":"1","name":"English"},{"id":"3","value":"Ceci est mon premier texte","key":"my_first_text","language_id":"3","name":"French"}],"num_rows":2}
Now when i click on submit it displays the error:
Error: a.push is not a function
The response object contains 2 keys result and num_rows result is an array. The reason i am not using isArray parameter in resource object is in case if any error occured in server like session time out, access not allowed etc. the server returned a object contains error msg.
Problem is solved by modifying the update function like:
$scope.submit = function() {
TextResource.update(
{'language':$scope.languages},
function(data) {
if( data.type == 'success' ) {
$location.path('texts');
} else {
$scope.alerts.push({type:data.type, msg:data.message});
}
},
function(error) {
var httpError = new HttpStatusMessage(error.status);
$scope.alerts.push({type:'error', msg:httpError.msg});
});
}
I was directly posting an array in update which throws the error. So encapsulating in another key solved the problem.
Related
I get a value of "True" in my response. How come my debugger and alert and AccessGranted() in the .then of my $http is not being invoked. Below is my Script:
app.controller("LoginController", function($scope, $http) {
$scope.btnText = "Enter";
$scope.message = "";
$scope.login = function() {
$scope.btnText = "Please wait...";
$scope.message = "We're logging you in.";
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
}).then(function (response) {
debugger;
alert(response.data);
if (response.data == "True") {
AccessGranted();
} else {
$scope.message = response.data;
$scope.btnText = "Enter";
}
},
function (error) {
$scope.message = 'Sending error: ' + error;
});
}
$scope.AccessGranted = function() {
window.location.pathname("/Home/HomeIndex");
}
});
This is in my HomeController
public ActionResult HomeIndex()
{
var am = new AuditManager();
var auditModel = new AuditModel()
{
AccountId = 0,
ActionDateTime = DateTime.Now,
ActionName = "Home",
ActionResult = "Redirected to Home"
};
am.InsertAudit(auditModel);
return View("Index");
}
Please see image for the response I get.
seems like your approach is wrong
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Try this,
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
})
.then(function (response) {
console.log(response);
},
function (error) {
console.log(error);
});
And check your browser console for logs or any errors
Make sure the response is application/json content type, and content is json.
You can also write own httpProvider for check result from server
module.config(['$httpProvider', function ($httpProvider) {
...
I would suggest you to code like this instead of then so whenever there is success, The success part will be invoked.
$http.get('/path/').success(function (data) {
$scope.yourdata = data.data;
//console.log($scope.yourdata);
}).error(function (error){
//error part
});
It's been a while since I've used $resource for managing my service calls.
For some reason, all my calls are working ok and reaching my REST end-points, basically /api/profile and /api/profile/:id.
But for some reason, my put returns as 404.
Anyone have an Idea of what may be going on.
Thanks and Cheers!
'use strict';
angular.module('chainLinkApp')
.config(['$stateProvider', function($stateProvider){
$stateProvider
.state('profile', {
url:'/profile/:id',
templateUrl:'views/profile.html',
controller:'ProfileController',
controllerAs:'profile'
});
}])
.controller('ProfileController',['$scope', '$http', 'profileFactory', function($scope, $http, profileFactory){
$scope.updateMode = false;
$scope.comments = profileFactory.getProfiles.go().$promise.then(function(response){
$scope.comments = response;
});
$scope.getProfile = function(commentId){
$scope.comment = profileFactory.getProfile.go({id:commentId}).$promise.then(function(response){
$scope.comment = response;
$scope.updateMode = true;
}, function(error){
return console.log('An error has occured', error);
});
};
$scope.addProfile = function(comment){
profileFactory.postProfile.go(comment).$promise.then(function(){
console.log('Your post was a success');
$scope.comment = {};
}, function(error){
console.log('There was an error: ', error);
});
};
$scope.updateProfile = function(comment){
profileFactory.updateProfile.go(comment._id, comment).$promise.then(function(response){
console.log('Your profile has been updated');
$scope.updateMode = false;
$scope.comment = {};
}, function(error){
console.log('There is an error: ', error);
});
};
}])
.factory('profileFactory', ['$resource', function($resource){
return{
getProfiles: $resource('/api/profile', {}, { go: { method:'GET', isArray: true }}),
getProfile: $resource('/api/profile/:id',{},{ go: { method: 'GET', params: { id: '#id' }}}),
postProfile: $resource('/api/profile', {}, { go: { method: 'POST' }}),
updateProfile: $resource('/api/profile/:id', {}, { go: { method: 'PUT', params: { id:'#id' }}})
};
}]);
The way of you are using $resource is strange, it should be like this:
.factory('UserService', function($resource) {
return $resource('/api/users/:id', {}, {
'create': { method: 'POST' },
'update': { method: 'PUT', params: { id: '#id'} }
});
})
Then you call the service like this: UserService.create(theUserobj, function(result) { ... })
I am trying to make an update to an existing object but get the following error $scope.entry.update is not a function.
I created a service called 'budgetResource'
"use strict";
angular.module("common.services").factory("budgetResource", ["$resource", "appSettings", budgetResource])
function budgetResource($resource, appSettings) {
return $resource(appSettings.serverPath + "api/budget/:id", null,
{
'update': { method: 'PUT', isArray: true },
'delete': { method: 'DELETE', isArray: true },
'save': { method: 'POST', isArray: true }
});
}
Herewith the function in my controller where budgetResource service is injected with the function $scope.updateBudgetAmount being called.
$scope.updateBudgetAmount = function (categoryId) {
$scope.entry = new budgetResource();
$scope.entry = {
"budgetAmount": $scope.budgetAmount,
"categoryId": categoryId
}
$scope.entry.update({ id: categoryId },
function (data) {
$scope.categories = data;
$scope.category = "";
},
function (error) {
$scope.message = error.statusText;
});
}
which in turn calls the webapi method
public IHttpActionResult Put(int id, [FromBody]Category cat)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
BudgetRepository repo = new BudgetRepository();
var categories = repo.SaveCategory(cat);
return Ok(categories);
}
How can modify this so that it is dine correctly?
After you do $scope.entry = {...},$scope.entry becomes a plain javascript object, so $scope.entry.update is not exist.
i have the following code for save operation:
here is my angular service: this already returns the promise
factory('customersaveService', function ($http, $q) {
var factoryObject = {};
factoryObject.SaveNewUserSrv = function(data) {
var deffered = $q.defer();
$http({
url: 'CustomerTest1/SaveNewUser',
method: 'POST',
headers: { 'content-type': 'application/json' },
data: JSON.stringify({ 'cust': data }),
})
.success(function (d) {
deffered.resolve(d);
})
.error(function (e) {
deffered.reject(e);
});
}
return factoryObject;
});
in here the promise is returned. therefore it shoudl not throw the error
"TypeError: Cannot read property 'then' of undefined"
the error comes from the controller's code:
$scope.SaveCustomer = function (data)
{
if ($scope.ButtonText == 'Save')
{
$scope.message = "";
$scope.submitted = true;
$scope.User = data;
console.log($scope.User);
customersaveService.SaveNewUserSrv($scope.User).then(function (d) { <=== error line
console.log('before success part');
if (d == 'success')
{
console.log('im in success part');
clearform();
}
},
function (e) {
});
}
}
why this throws the error when the promise was returned?
1.Create service like below :
2.No need of $q service.
factory('customersaveService', function ($http) {
var factoryObject = {};
factoryObject.SaveNewUserSrv = function(data) {
return $http({
url: 'CustomerTest1/SaveNewUser',
method: 'POST',
headers: { 'content-type': 'application/json' },
data: JSON.stringify({ 'cust': data }),
})
}
return factoryObject;
});
factory('customersaveService', function ($http) {
var SaveNewUserSrv = function(data) {
return $http({
url: 'CustomerTest1/SaveNewUser',
method: 'POST',
headers: { 'content-type': 'application/json' },
data: { 'cust': data }
});
};
return {
SaveNewUserSrv: SaveNewUserSrv
};
});
And in the controller, sure you inject the service customersaveService
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;
}
]);