I'm trying to make an update function to replace some data on an user.
I've created the factory:
factory('Details', ['$resource', function ($resource) {
return $resource('/api/client/:id', null, {
'update': { method: 'PUT'}
});
}]);
and the controller:
.controller('ClientDetails', function ($scope, Details, $routeParams) {
$scope.client = Details.query({ id: $routeParams.id });
$scope.editClient = function () {
$scope.client.$update();
}
});
and when entering function editClient() it throws and error:
$scope.client.$update is not a function
What have I done wrong? Thanks
By default, the query method is defined to return an array of instances: 'query': {method:'GET', isArray:true}, see documentation for ng-resource. And the array does not have the $update method. From your code, you need to use the get to fetch the instance, like this:
$scope.client = Details.get({ id: $routeParams.id });
$scope.editClient = function () {
$scope.client.$update();
}
Related
First i want to say that i'm fairly new to AngularJS, so it might be that i'm asking my question with some oddnes.
I'm trying to pass a string to a factory which in return gives me a result from my database. When i hardcode the values, everything works. But when i try to pass inn values from my view/controller things stop working.
Here is my factory:
healthServices.factory('Entry',
function ($resource) {
return $resource('http://localhost:60673/api/hierarchy/:id', { id: '#id'}, {
query: { method: 'GET', isArray: true }
});
});
Here is the controller im using:
$scope.changeData = function (type) {
$scope.entry = new Entry();
$scope.id = type;
$scope.healthData = $scope.entry.$query({ id: $scope.id });
}
And this is how it looks in my html:
<button ng-click="changeData('someValue')">
At the moment i keep getting
TypeError: value.push is not a function
As i mentioned im quite new to this, so I might be far off. Any help would be very much appreciated.
What is intended by this line of code?
$scope.entry = new Entry();
Entry is your service you want to call.
You should pass this into your controller via dependency injection.
Angular does the 'new' for you.
myApp.controller('myCntrl', HomeCtrl);
HomeCtrl.$inject = ['$scope', 'Entry'];
function HomeCtrl($scope, Entry) {
...
}
I am not seeing any wrong with your $resource configuration.
var myApp = angular.module('myApp',['ngResource']);
myApp.factory('Entry', function ($resource) {
return $resource('http://localhost:60673/api/hierarchy/:id', { id: '#id'}, {
query: { method: 'GET', isArray: true }
});
});
myApp.controller('myCtrl', ['$scope', 'Entry', function($scope, Entry){
$scope.changeData = function (type) {
$scope.entry = new Entry();
$scope.id = type;
$scope.healthData = $scope.entry.$query({ id: $scope.id });
}
}]);
i am getting below in console
GET http://localhost:60673/api/hierarchy/someValue
error lies on other part of the code, please post your controller completely.
I'm getting this error "Error: [$resource:badcfg] Error in resource configuration for action 'get'. Expected response to contain an object but got an array"
and I don't know how to fix it. I have this service
angular.module('messages').factory('Messages', ['$resource',
function ($resource) {
return $resource('api/messages/:username', {
username: '#username'
});
}]);
and this in controller:
$scope.findOne = function () {
$scope.messages = Messages.get({
username: $routeParams.username
});
console.log($scope.messages);
};
For this route I have in API controller this
exports.read = function (req, res) {
res.json(req.message);
};
I know that I have to use $resource action isArray = true, but I don't know where to put it. I tried to do something like this:
angular.module('messages').factory('Messages', ['$resource',
function ($resource) {
return $resource('api/messages/:username', {
username: '#username'
},
{'query': {method: 'GET', isArray: true}});
}]);
but without result and still same error.
In your controller:
$scope.findOne = function () {
$scope.messages = Messages.query({
username: $routeParams.username
});
console.log($scope.messages);
};
query Instead of get, should solve it.
Use Messages.query(...) instead of method get()
What you did is correct, but you have the use the method you just created ('query'), so the call would look like this:
$scope.findOne = function () {
Messages.query({
username: $routeParams.username
}).$promise.then(function (response) {
$scope.messages = response;
console.log($scope.messages);
});
};
I am passing three parameters from my controller to the factory following way.
In my controller I am trying to pass three parameters id,sdt and edt ..
$scope.val = function () {
$scope.tech = techRepository.getTech.query({ id: $scope.id, sdt: $scope.sDate, edt: $scope.eDate }, function(data) {
scope.tech = data;
});
};
In my factory I have
App.factory('techRepository', ['$resource', function ($resource) {
return {
getTech: $resource('/api/Tech/GetRange/:id', {id: '#id', start: '#sdt', end: '#edt'}, {query: {method: 'GET', isArray:true}})
};
}]);
When I run this I get Bad Request error. Please let me know how to pass multiple parameters. Thanks
This works fine, presuming you want :id in your query string to be replaced with the value of $scope.id, and two query parameters (sdt and edt) attached like:
http://www.example.com/api/Tech/GetRange/123?edt=20140610&sdt=20140609
It seems like you may instead be expecting a URL that looks like:
http://www.example.com/api/Tech/GetRange/123?end=20140610&start=20140609
... in which case, your code should look like:
// in controller
$scope.val = function () {
$scope.tech = techRepository.getTech.query({ id: $scope.id, start: $scope.sDate, end: $scope.eDate }, function(data) {
scope.tech = data;
});
};
.factory('techRepository', ['$resource', function ($resource) {
return {
getTech: $resource('/:id', {id: '#id'}, {query: {method: 'GET', isArray:true}})
};
}]);
Demo
I am trying to write the jasmine test case for a function which in turn calls another function and returns a response. Seems like the function is called but i am not getting the value that is set inside the function.
Controller Function:
angular.module('serviceApp')
.controller('startWorkscopeCtrl', function ($rootScope, $log, $scope, CommentService) {
$scope.getTextById = function (id) {
CommentService.get({ id: id }, function (response) {
$scope.text = response;
$scope.textCount = $scope.text.length;
});
};
});
The service is referenced in another js file where it makes the rest service call to the backend service.
angular.module('restServiceModule', ['ngResource'])
.factory('CommentService', function($resource){
return $resource(
{
get: {
method: 'GET',
isArray: true,
url: window.urlPrefix + '/commentservice/:id',
params: {
id: '#id'
}
}
});
})
Test Case:
var mockTextComment;
var fakeText = ['testPass'];
beforeEach(function(){
mockTextComment = {
get: function(){
return fakeText;
}
};
});
it('should get comments by asset id', function () {
spyOn(mockTextComment, 'get');
inject(function ($controller) {
ctrl = $controller('startWorkscopeCtrl', {
$scope: scope,
CommentService: mockTextComment
});
scope.getTextById(40107);
expect(scope.textCount).toEqual(1);
});
});
With this, i am getting the below error:
**Expected undefined to equal 1.
Error: Expected undefined to equal 1.**
Not sure where i am doing wrong. Any pointers on this will be helpful.
It looks like CommentService.get does not return a value; it calls back a function upon completion. Therefore, a CommentService mock would look like this:
var mock = {
get : function(arg1, callback){
callback(fakeText);
}
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I got this angular factory:
var productApp = angular.module('productApp', ['ngRoute', 'LocalStorageModule', 'angularSlideables', 'ui.bootstrap']);
productApp.factory('productFactory', function($http, localStorageService, $q) {
var factory = {};
factory.getProductById = function(prod_id) {
if(prod_id !== '') {
$http({
url: 'rest/message/getProductById/' + prod_id,
method: 'GET'
}).success(function(data, status) {
return data;
}).error(function(data, status){
// do nothing
});
}else {
alert("There was an error while passing the ID. Please refresh the page and try again");
}
}
return factory;
});
Injecting the factory in a controller and calling to the "getProductById" function:
productApp.controller('ModalInstanceCtrl', function ($scope, $modalInstance, productFactory, prodId) {
console.log("this is the prod id " + prodId);
// search product in the database
$scope.prod = productFactory.getProductById(prodId);
console.log($scope.prod);
$scope.ok = function () {
console.log($scope.prodData);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Now, don't know what's wrong with it... the function RETURNS the data because i did a console.log(data) and saw all the response, but in the controller if i inspect the $scope.prod, it's undefined. It's not returning the data back from the function.
(Just in case you guys ask, the "prodId" in the controller parameter is fine, and retrieving that from another controller)
How can i solve this? :(
Thanks in advance.
The pattern I have used to solve this problem is to pass in the success & error callback functions to the factory... like this:
var productApp = angular.module('productApp', ['ngRoute', 'LocalStorageModule', 'angularSlideables', 'ui.bootstrap']);
productApp.factory('productFactory', function($http, localStorageService, $q) {
var factory = {};
factory.getProductById = function(prod_id, successCallback, errorCallback) {
if(prod_id !== '') {
$http({
url: 'rest/message/getProductById/' + prod_id,
method: 'GET'
})
.success(successCallback)
.error(errroCallback);
} else {
alert("There was an error while passing the ID. Please refresh the page and try again");
}
}
return factory;
});
and then:
productApp.controller('ModalInstanceCtrl', function ($scope, $modalInstance, productFactory, prodId) {
console.log("this is the prod id " + prodId);
// search product in the database
productFactory.getProductById(prodId, function successCallback(data) {
$scope.prod = data;
}, function errorCallback(data, status) {
alert("An error occurred retrieving product. Please refresh the page & try again.");
});
console.log($scope.prod);
$scope.ok = function () {
console.log($scope.prodData);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
By doing it this way instead, you have access to the scope in the controller & can do whatever you need to with the returned data.
Here's what I do. I'm using $resournce instead of $http, but it should be enough to get you going. You may even want to use the $resource since it has the built in fns.
My factory:
.factory('WorkOrder', function($resource){
// $resource Usage: $resource(url[, paramDefaults][, actions]);
return $resource('/controller/get/:id.json', {}, {
/*
* By default, the following actions are returned; modify or add as needed
* { 'get': {method:'GET'},
* 'save': {method:'POST'},
* 'query': {method:'GET', isArray:true},
* 'delete': {method:'DELETE'} };
*/
});
})
My controller:
// get the work order data using the work order id from the tag attribute
var getWO = function() {
WorkOrder.get({woId:$attrs.id},
// success callback
function(response) {
// Assign the work order data to the scope
$scope.WorkOrder = response.WorkOrder;
},
// fail callback
function(response) {
// whatever...
}
);
};
getWO();
I put my success and fail fns in my controller because that's where I most likely know how I want to respond to success or failed calls. I also assign the function to a variable and then call it right after in case I want to include the fn call inside a $timeout or call it elsewhere.
Hope this answers your question.