I'm trying to update data in an object on the view, my service looks like this:
.service('Tag', function Tag($resource, API) {
return $resource(API.baseUrl + '/api/tags/:id', { id:'#_id' }, {
update: {
method: 'PUT', params: {id: '#id'}},
delete: {
method: 'DELETE', params: {id: '#id'}}
})
});
my Controller
angular.module('myApp')
.controller('EditorTagsCtrl', function ($scope, Tag,$routeParams) {
$scope.tag = Tag.query()
$scope.updateTag = function()
{
Tag.update()
console.log ('working?')
}
});
Im getting a 404 error and the data is not passing to the back end.
Please help
Related
So I'm currently working with $ngResouce. My api: api/Content/resource/user.post.failed returns the following:
{
"user.post.failed": "Thing.."
}
app.factory('testResource', function ($resource) {
return $resource(apiurl + '/Content/resource/:resourcename', {}, {
show: { method: 'GET', isArray: false, params: {resourcename: '#resourcename'} },
update: { method: 'PUT', params: {id: '#id'} },
delete: { method: 'DELETE', params: {id: '#id'} }
})
});
This is what I call in my controller
$scope.test = testResource.get({resourcename: 'test'});
The question is actually really simple; how do I get just the 'content part' so test. I'm now getting the whole JSON part back.
So the scope test is now: {"user.post.failed":"Thing.."}
And I want the scope to be just Thing.
Probably really simple, but I couldn't find the answer.
Use the $promise property of the object to see errors:
$scope.test = testResource.get({resourcename: 'test'});
$scope.test.$promise.catch(function onReject(response) {
console.log('ERROR: ',response.status);
console.log(response);
});
So the scope test is now: {"user.post.failed":"Thing.."} And I want the scope to be just Thing.
console.log($scope.test["use.post.failed"]);
Use the property accessor syntax.
For more info see MDN JavaScript Reference -- Property Accessors
HTML
{{ test["use.post.failed"] }}
testResource.get({resourcename: 'test'}, function(data) {
$scope.test = data['user.post.failed'];
})
I am new to Angular and having hard time to understand how to get the value from a resolved promise. I used $q.all([element1.$promise, e2.$promise]). I got the element1 which is a json object. For, element2 which is a scalar containing 2.0. I tried element[1] just like element[0] but it contains no property, so I don't know how to get the value. I tried .val, .data, etc. I know both the web api and angular are getting 2.0.
resolve: {
accountResource: "accountResource",
account: function(accountResource, $stateParams, $q) {
var info = accountResource.get({ accountId: $stateParams.accountId });
var currentBalance = accountResource.getCurrentBalance({ accountId: $stateParams.accountId });
return $q.all([info.$promise, currentBalance.$promise]);
}
vm.account = account[0];
vm.currentBalance = account[1];
resource function
function accountResource($resource) {
var webApiUrl = "https://localhost:44301";
return $resource(webApiUrl + '/api/account/:accountId', {}, {
get: {
method: 'GET'
},
query: {
method: 'GET',
isArray: true,
url: webApiUrl + '/api/account/search/:queryMethod/:queryString'
},
getCurrentBalance: {
method: 'GET',
url: webApiUrl + '/api/account/getcurrentbalance/:accountId'
}
});
}
You can call $q.all likes this (with dictionary instead of array):
return $q.all({info: info.$promise, currentBalance: currentBalance.$promise})
And after that get information in this way:
vm.account = account.info;
vm.currentBalance = account.currentBalance;
Try to rewrite your resource as this:
function accountResource($resource) {
var webApiUrl = "https://localhost:44301";
// Add second parameter {accountId: "#accountId"}
return $resource(webApiUrl + '/api/account/:accountId', {accountId: "#accountId"}, {
get: {
method: 'GET'
},
query: {
method: 'GET',
isArray: true,
url: webApiUrl + '/api/account/search/:queryMethod/:queryString'
},
getCurrentBalance: {
method: 'GET',
url: webApiUrl + '/api/account/getcurrentbalance/:accountId'
}
});
}
Updated
You can add transformResponse property to your getCurrentBalance function in accountResoure. And transform your value from API to json format.
getCurrentBalance: {
method: 'GET',
url: webApiUrl + '/api/account/getcurrentbalance/:accountId',
transformResponse: function (balanceFromApi) {
return { balance: balanceFromApi };
}
}
And finally you can get information, likes this:
vm.account = account.info;
vm.currentBalance = account.balance;
I tested it with $httpBackend service and everything is fine now. 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)
I am having trouble getting resolve in $routeProvider to automatically update the view.
I am trying to convert an example (chapter 22) in Adam Freeman's Pro Angular book from Deployd to Express-Mongo. A possible hint is that the automatic refresh works using a local version of Deployd. When I switched to local Express and Mongo backend (after making the id to _id changes), the automatic view update no longer works.
When using Express-Mongo, I have to manually execute $route.reload() function to get show the updated changes from the database. I am new to angular so any hints are appreciated.
This heavy handed Delete works:
$scope.deleteProduct = function (product) {
product.$delete();
$route.reload();
$location.path("/list");
}
The below version Doesn't work. I was under the (probably mistaken) impression that the 'resolve' property in $routeProvider updates the view when the data is returned. With the below code, I get a Type Error: Undefined is not a function
$scope.deleteProduct = function (product) {
product.$delete().then(function () {
$scope.data.products.splice($scope.data.products.indexOf(product), 1);
});
$location.path("/list");
}
Console Log Errors
TypeError: undefined is not a function
at http://localhost:8080/bower_components/angular-resource/angular-resource.js:530:25
at Array.forEach (native)
at forEach (http://localhost:8080/bower_components/angular/angular.js:302:11)
at angular.module.factory.Resource.(anonymous function).$http.then.value.$resolved (http://localhost:8080/bower_components/angular-resource/angular-resource.js:529:17)
at deferred.promise.then.wrappedCallback (http://localhost:8080/bower_components/angular/angular.js:10905:81)
at deferred.promise.then.wrappedCallback (http://localhost:8080/bower_components/angular/angular.js:10905:81)
at http://localhost:8080/bower_components/angular/angular.js:10991:26
at Scope.$get.Scope.$eval (http://localhost:8080/bower_components/angular/angular.js:11906:28)
at Scope.$get.Scope.$digest (http://localhost:8080/bower_components/angular/angular.js:11734:31)
at Scope.ng.config.$provide.decorator.$delegate.__proto__.$digest (<anonymous>:844:31) angular.js:9383
Below is the code for the module
angular.module("exampleApp", ["ngResource", "ngRoute"])
.constant("baseUrl", "http://localhost:8080/api/products/")
.factory("productsResource", function ($resource, baseUrl) {
return $resource(baseUrl + ":id", { id: "#_id" },
{
create: { method: "POST" , isArray: true },
save: { method: "PUT", isArray: true },
delete: {method: "DELETE", isArray: true},
update: {method: "PUT", isArray: true},
query: {method: "GET", isArray: true}
})
})
.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
...
$routeProvider.otherwise({
templateUrl: "/views/tableView.html",
controller: "tableCtrl",
resolve: {
data: function (productsResource) {
return productsResource.query();
}
}
});
})
.controller("defaultCtrl", function ($scope, $location, productsResource, $route) {
$scope.data = {};
$scope.deleteProduct = function (product) {
product.$delete().then(function(products) {
//Success
console.log("Success"); //Don't Get Here
$scope.data.products.splice($scope.data.products.indexOf(product), 1);
}, function(errResponse) {
//Failure (Code Produces a Type Error: Undefined is not a function)
console.log("Error: " + errResponse);
});
$location.path("/list");
}
})
The Table View Controller that is bound to the $routeProvider.otherwise
.controller("tableCtrl", function ($scope, $location, $route, data) {
$scope.data.products = data;
$scope.refreshProducts = function () {
$route.reload();
} })
I think you should redirect when the delete is complete:
$scope.deleteProduct = function (product) {
product.$delete().then(function () {
$scope.data.products.splice($scope.data.products.indexOf(product), 1);
$location.path("/list");
});
}
You have missed } at the and of line with text:
delete: {method: "DELETE", isArray: true
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.