Getting an error while creating factory object - angularjs

I have a module and controller which are created like :
var API_ENGINE_URL = 'localhost/angular/';
var mainApp = angular.module('mainApp', ['ngRoute', 'ngResource']);
mainApp.controller('productController', ['$scope', 'ProductFactory', 'ProductListFactory','$routeParams', function ($scope, ProductFactory,routeParams, ProductListFactory) {
var productList = new ProductListFactory();// THROWS ERROR HERE
var promise = productList.$get({id: $routeParams.category_id}).$promise;
promise.then(function (productList) {
$scope.productList = productList;
});
}]);
and the Model is created like this, files are properly loaded
mainApp.factory('ProductListFactory', ['$resource',function ($resource) {
return $resource(API_ENGINE_URL + 'category/:id/items', {}, {
get: {method: 'GET', params: {category_id: '#category_id', id: '#id'},isArray:true,url:API_ENGINE_URL+'product?store_id=:storeId'},
save: {method: 'GET', isArray: true}
});
}]);
I am getting an error in the controller like below. what could be the error. Stuck for a long time

In a factory function, the return value is what's cached and injected by Angular. There is no need to instantiate it yourself.
Try this:
mainApp.controller('productController', ['$scope', 'ProductFactory', 'ProductListFactory','$routeParams', function ($scope, ProductFactory,routeParams, ProductListFactory) {
var promise = ProductListFactory.$get({id: $routeParams.category_id}).$promise;
promise.then(function (productList) {
$scope.productList = productList;
});
}]);

Problem is in ordering should be :
['$scope', 'ProductFactory', 'ProductListFactory','$routeParams', function ($scope, ProductFactory,ProductListFactory,$routeParams)

Related

Error: unable to get property 'call' of undefined or null reference

I am using AngularJs. When getting data from controller.js to service.js, I am getting the error. Below is the code used:
//controller.js
angular.module('testApp.controllers', []).
controller('testController', function ($scope, testAPIService, $timeout, $window, $location, $anchorScroll, $http) {
$scope.show = function() {
testAPIService.getDataSummary().success(function (response) {
console.log(response);
}).error(function (response) {
alert(response.responseText);
});
}
});
In Service.js
angular.module('testApp.services', []).
factory('testAPIService', ['$http', function ($http) {
var testAPIService = {};
testAPIService.getDataSummary = function () {
var request = {
url: urlBase + 'GetDataSummary',
method: 'Get',
headers: {
'accept': 'application/json'
}
}
return $http(request);
};
return testAPIService;
}]);
How to fix this? Thanks
This might be the result of including any of your app javascript file before the angularjs file.
Make sure you include angularjs file before the rest of your app files.
You're creating two different modules:
The first module testApp.controllers is created when you create the controller
Another module testApp.services is created when you create the service.
So the controller and the service are never part of the same module!
Try attaching to the same testApp module as follows:
app.js
// With [] means to create a new module.
angular.module('testApp', []);
controller.js
// Without [] means to retrieve an existing module.
angular.module('testApp').
controller('testController', function($scope, testAPIService, $timeout, $window, $location, $anchorScroll, $http) {
$scope.show = function() {
testAPIService.getDataSummary().success(function(response) {
console.log(response);
}).error(function(response) {
alert(response.responseText);
});
}
});
service.js
// Without [] means to retrieve an existing module.
angular.module('testApp').
factory('testAPIService', ['$http', function($http) {
var testAPIService = {};
testAPIService.getDataSummary = function() {
var request = {
url: urlBase + 'GetDataSummary',
method: 'Get',
headers: {
'accept': 'application/json'
}
}
return $http(request);
};
return testAPIService;
}]);
index.html
And change your ng-app directive to point to the testApp module
<html ng-app="testApp">

Angular Resource error in console

I ve got an angular resource service which then returns the data to a controller and I get all the data plus the data by name.
My application works just fine in the browser but I get a resource error in the console. Bad resource configuration.
I had a look in various questions and everyone states that I need to set the configuration property isArray to either false or true.
I have tried to do this but I still get an error.
Any ideas much appreciated.
Here is my service :
(function() {
var app = angular.module('test');
app.service('ContactResource', function($resource) {
return $resource('/contacts/:firstname', {},
{'update': {method: 'PUT'}},
{'query': { method: 'GET', isArray: true }},
{'get': { method: 'GET', isArray: false }}
);
});
}());
And here is my controller:
(function() {
var app = angular.module('test');
app.controller('contactsCtrl', function($scope, $routeParams, ContactResource) {
$scope.contacts = ContactResource.query();
$scope.singlecontact = ContactResource.get({firstname: $routeParams.firstname});
});
}());
The error I am getting is : Error: [$resource:badcfg] http://errors.angularjs.org/1.4.2/$resource/badcfg?p0=get&p1=object&p2=array&p3=GET&p4=%2Fcontacts
When I click it says :
Error in resource configuration for action get. Expected response to contain an object but got an array (Request: GET /contacts)
When I get the url is /contacts the response is :
[{EmailAddress:some#email.com, etc}]
When the url is /contacts/firstname the response is :
{EmailAddress:some#email.com,etc}
I solved the problem by adding a new controller called single controller and by separating the service into two functions. Here is how my code looks like now.
This is the service:
(function() {
var app = angular.module('test');
app.service('ContactResource', function($resource, $routeParams) {
this.all = function() {
return $resource('/contacts', {},
{'query': { method: 'GET', isArray: true }}
)};
this.single = function() {
return $resource('/contacts/:firstname', {firstname: '#firstname'},
{'query': { method: 'GET', isArray: false }}
);
}
});
}());
And the controllers :
(function() {
var app = angular.module('test');
app.controller('contactsCtrl', function($scope, $routeParams, ContactResource) {
$scope.contacts = ContactResource.all().query();
});
app.controller('singleCtrl', function($scope, $routeParams, ContactResource) {
$scope.singlecontact = ContactResource.single().query({firstname: $routeParams.firstname});
});
}());
For some reason which I am still not sure $resource wouldn't accept them into the same controller.

Angular Js : undefined value in pop up

I get a problem in AngularJS when getting data from JSON using service factory ($resource)
services.factory('GetCustomerByEmailFactory', function ($resource) {
return $resource(url + '/customerService/getCustomerByMail?email=:email', {}, {
getByMail: { method: 'GET', params: {email: '#email'} }
});
});
this service works well
but the controller part doesn't work
app.controller('CustomerCreationCtrl', ['$scope','PostCustomerFactory', '$location','Subscription','AddNotificationFactory','$routeParams','GetCustomerByEmailFactory',
function ($scope, PostCustomerFactory, $location,Subscription,AddNotificationFactory,$routeParams,GetCustomerByEmailFactory) {
$scope.customer ={};
$scope.not ={};
$scope.aftercustomer ={};
$scope.createNewCustomer = function(){
Number($scope.customer.PhoneNumber);
$scope.customer.SubscriptionDate = "1990-02-23T00:00:00";
$scope.customer.ManagerIdCustomer=1;
PostCustomerFactory.create($scope.customer);
var customer = GetCustomerByEmailFactory.getByMail({email:$scope.customer.Email}).$promise;
customer.then(function (responce){
$scope.aftercustomer = responce;
window.alert($scope.aftercustomer.Id);
$scope.not.CustomerId = $scope.aftercustomer.Id;
$scope.not.ManagerId = $routeParams.id;
AddNotificationFactory.create($scope.not);
});
$location.path("/login");
};
}]);
the window.alert show me an undefined value so that it doesn't get the data

AngularJS pass parameter from Controller to Service

I don't know how to pass data from the controller to the service as method arguments... I need to set in the controller the headers variable which is later added to the service which adds this later on to the http call
controller
angular.module('userControllers', []).
controller('userController', ['$scope', '$q', 'Users', '$location',
function($scope, $q, Users, $location) {
$scope.viewUser = function(userId) {
$location.path('/users/'+userId);
};
$scope.createUser = function () {
$location.path('/users/create');
};
headers = {service:'json',resource:'users'};
$scope.users = Users.query(headers);
$scope.users.$promise.then(function(result){
$scope.users = result;
});
}]);
service
angular.module('userServices', ['ngResource']).
factory('Users', ['$resource', '$q', function($resource, $q){
var factory = {
query: function (headerParams) {
var data = $resource('http://localhost:8080/gateway', {}, {
query: {
method: 'GET',
isArray: true,
headers: headerParams
}
});
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
In this setup I'm getting Error: [$injector:unpr] Unknown provider: UserProvider <- User ... not really sure how to fix this one out ...
Later edit : code cleanup... posted full code and new error
TypeError: Cannot read property 'then' of undefined
at new <anonymous> (http://localhost/frontend-pdi-angular-js/js/controllers/users.js:16:38)
at invoke (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:3918:17)
at Object.instantiate (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:3929:23)
at https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:7216:28
at link (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-route.js:913:26)
at nodeLinkFn (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:6648:13)
at compositeLinkFn (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:6039:13)
at publicLinkFn (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:5934:30)
at boundTranscludeFn (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:6059:21)
at controllersBoundTransclude (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.js:6669:18) <div ng-view="" class="ng-scope">
Later edit #2 : some working code, but using no ngResource whatsoever
angular.module('userControllers', ['userServices']).
controller('userController',
['$scope', '$q', 'Users', '$location', '$http',
function($scope, $q, Users, $location, $http) {
headerParams = {service:'json',resource:'users'};
$scope.users = $http({method: 'GET', url: 'http://localhost:8080/gateway', headers: headerParams, isArray:true}).
success(function(data, status, headers, config) {
$scope.users = data;
console.log(data);
}).
error(function(data, status, headers, config) {
console.log(status);
});
}]);
As others mentioned, you are using a non-existent reference to a provider ($promise) in your code. By simply setting the deferred to $scope.users and then acting on the 'then' of that deferred, you can solve this problem.
You can also simplify it a bit. You are setting the deferred on the $scope object and then you're overwriting that with the resolved value of the deferred. So you can do this instead:
Users.query(headers).then(function(result){
$scope.users = result;
});
if you want to assign the deferred to a separate variable:
var deferred = Users.query(headers);
deferred.then(function(result){
$scope.users = result;
});
angular.module('userControllers', ['userServices']).
controller('userController',
['$scope', '$q', 'Users', '$location',
function($scope, $q, Users, $location) {
headers = {service:'json',resource:'users'};
Users.query(headers).then(function(result){
$scope.users = result;
});
}])
angular.module('userServices', ['ngResource']).
factory('Users', ['$resource', '$q', function($resource, $q){
var factory = {
query: function (headerParams) {
var data = $resource('http://localhost:8080/gateway', {}, {
query: {
method: 'GET',
isArray: true,
headers: headerParams
}
});
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
Try this. Your not include the userServices module into the userControllers module and you can omit $scope.users = Users.query(headers); part because if you put this this will call the query method.
replace controller with this code:
angular.module('userControllers', []). controller('userController', ['$scope', '$q', 'Users', '$location', function($scope, $q, Users, $location) {
$scope.viewUser = function(userId) {
$location.path('/users/'+userId);
};
$scope.createUser = function () {
$location.path('/users/create');
};
headers = {service:'json',resource:'users'};
Users.query(headers).$promise.then(function(result){
$scope.users = result;
});
}]);
and factory with this code :
angular.module('userServices', ['ngResource']).
factory('Users', ['$resource', '$q', function($resource, $q){
var factory = {
query: function (headerParams) {
return $resource('http://localhost:8080/gateway', {}, {
query: {
method: 'GET',
isArray: true,
headers: headerParams
}
})
}
}
return {
query: factory.query
}
}]);
i think this will help you.

AngularJS: How to wait for $resource to finish?

I have a controller:
app.controller('ProductDetailCtrl', ['$scope', '$q', '$resource', 'Product', function($scope, $q, $resource, Product) {
$scope.product = {};
$scope.init = function(id)
{
$scope.product = Product.get({productId: id});
}
$q.all([$scope.product.$promise]).then(function() {
$scope.selected_color = $scope.product.products_colors[0];
});
// $scope.selected_color = $scope.product.products_colors[0];
}]);
And a factory:
app.factory('Product', ['$resource', function($resource) {
return $resource("/api/products/:productId", {}, {
query: {method: 'GET', isArray: true},
});
}]);
However, when I load the page it gives me this:
Error: $scope.product.products_colors is undefined #http://localhost:3000/assets/products/controllers/productscontroller.js?body=1:11:5 qFactory/defer/deferred.promise.then/wrappedCallback#http://localhost:3000/assets/angular.js?body=1:11499:15 qFactory/ref/<.then/<#http://localhost:3000/assets/angular.js?body=1:11585:11 $RootScopeProvider/this.$get</Scope.prototype.$eval#http://localhost:3000/assets/angular.js?body=1:12609:9 $RootScopeProvider/this.$get</Scope.prototype.$digest#http://localhost:3000/assets/angular.js?body=1:12421:15 $RootScopeProvider/this.$get</Scope.prototype.$apply#http://localhost:3000/assets/angular.js?body=1:12713:13 bootstrap/doBootstrap/<#http://localhost:3000/assets/angular.js?body=1:1420:9 invoke#http://localhost:3000/assets/angular.js?body=1:3919:7 bootstrap/doBootstrap#http://localhost:3000/assets/angular.js?body=1:1419:1 bootstrap#http://localhost:3000/assets/angular.js?body=1:1432:5 angularInit#http://localhost:3000/assets/angular.js?body=1:1345:5 #http://localhost:3000/assets/angular.js?body=1:21818:5 jQuery.Callbacks/fire#http://localhost:3000/assets/jquery.js?body=1:3100:1 jQuery.Callbacks/self.fireWith#http://localhost:3000/assets/jquery.js?body=1:3212:7 .ready#http://localhost:3000/assets/jquery.js?body=1:3424:3 completed#http://localhost:3000/assets/jquery.js?body=1:3454:3
return logFn.apply(console, args);
How would I wait until the $resource finishes loading? I want to set one of my $scope variables based on the result of Product.get(..). I know that Product.get(..) is returning and object with a products_colors property because console.log says so
Use a callback:
Product.get({productId: id}, function(data) {
$scope.product = data;
});

Resources