Can't get array by $resource - javascript

Can't get array by $resource. Can you help me? When I use $http all is well
I have error in console:
TypeError: undefined is not a function
at http://127.0.0.1:9000/bower_components/angular-resource/angular-resource.js:597:29
at forEach (http://127.0.0.1:9000/bower_components/angular/angular.js:327:18)
at angular.module.provider.$get.Resource.(anonymous function).$http.then.value.$resolved (http://127.0.0.1:9000/bower_components/angular-resource/angular-resource.js:595:19)
at deferred.promise.then.wrappedCallback (http://127.0.0.1:9000/bower_components/angular/angular.js:11616:81)
at http://127.0.0.1:9000/bower_components/angular/angular.js:11702:26
at Scope.$get.Scope.$eval (http://127.0.0.1:9000/bower_components/angular/angular.js:12797:28)
at Scope.$get.Scope.$digest (http://127.0.0.1:9000/bower_components/angular/angular.js:12609:31)
at Scope.$get.Scope.$apply (http://127.0.0.1:9000/bower_components/angular/angular.js:12901:24)
at done (http://127.0.0.1:9000/bower_components/angular/angular.js:8487:45)
at completeRequest (http://127.0.0.1:9000/bower_components/angular/angular.js:8703:7)
I created a factory with method
coeffsResource.factory("CoeffsResources",['$resource',
function($resource) {
return $resource('/api/:action',{}, {
get_all_coeffs: { method:'GET', isArray:false, params: {action: 'getAllRegionCoefficients'} },
save_all_coeffs: { method:'POST', params: {action: 'storeAllRegionCoefficients'} },
get_manufacturer: { method: 'GET', isArray:true, params: {action: 'getAllManufacturers'} },
get_models: { method: 'GET', params: {action: 'getModels'} },
get_classes: {method: 'GET', params: {action: 'getClassesConfig'} },
get_regions: {method: 'GET', params: {action: 'getAllRegions'} },
get_ages_config: {method: 'GET', params: {action: 'getAgesConfig'} },
get_odometer: {method: 'GET', params: {action: 'getOdometersConfig'} },
get_tax_config: {method: 'GET', params: {action: 'getTaxConfig'} }
}, {stripTrailingSlashes: false})
}]);
Include factory in controller
angular.module('etachkaEvaluatorFrontendApp')
.controller('CoeffCtrl', function($scope, $http, $resource, $q, CoeffsResources) {
var coeffsResourcesObject = new CoeffsResources();
coeffsResourcesObject.$get_manufacturer().then(function() {
}, function() {
})
})

I think you need to inject the ngResource dependency.
angular.module('etachkaEvaluatorFrontendApp', ['ngResource'])

Why are you newing up a singleton? AngularJS Factories are not intended to work this way. See the AngularJS service docs for more information
Angular services are:
Lazily instantiated – Angular only instantiates a service when an
application component depends on it.
Singletons – Each component
dependent on a service gets a reference to the single instance
generated by the service factory.
Change your usage in CoeffCtrl to the following... (this also assumes you have correctly loaded the ngResource module at some earlier point in your application)
.controller('CoeffCtrl', function($scope, $http, $resource, $q, CoeffsResources) {
CoeffsResources.$get_manufacturer().then(function() {
}, function() {
})
For a better understanding on factory behavior I have crafted two simple demos. Note that these are not intended to solve your issues in a copy/paste fashion - but to demonstrate what happens when we new an AngularJS factory.
JSFiddle Link - demo - correct
JSFiddle Link - demo - incorrect - TypeError: undefined is not a function

Related

AngularJS: console.log does not display anything

I wrote a controller for login page. Here is my controller:
var authApp = angular.module('loginApp', [])
authApp.controller('LoginCtrl', ['$scope', '$location', 'loginFactory', function($scope, $location, loginFactory){
$scope.authenticate = function() {
loginFactory.login($scope.username, $scope.password)
.then(function(response) {
console.log(response.$statusText);
}, function errorCallBack(response) {
console.log(response.$statusText);
});
}
}]);
My service:
authApp.factory("loginFactory", function ($http) {
return{
login: function(username, password) {
var data = "username="+username+"&password="+password+"&submit=Login";
return $http({
method: 'POST',
url: 'http://localhost:8080/login',
data: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
});
}
When I debug the code, authentication seems successful and it did get into then function. However nothing displays in console. And I got a warning(?) saying undefined for the line console.log(response.$statusText);. It is not an error since it is not red. Why doesn't it print out anything?
Use response.statusText not response.$statusText. The documentation for AngularJS $http requests lists statusText as one of the properties of the response object - https://docs.angularjs.org/api/ng/service/$http

How can I change the structure of an AngularJS get request?

I have the following states as part of an AngularJS app:
.state('app.stages', {
url: '/stages',
views: {
'menuContent': {
templateUrl: 'templates/stages.html',
controller: 'StagesCtrl'
}
}
})
.state('app.stage', {
url: '/stages/:stageId',
views: {
'menuContent': {
templateUrl: 'templates/stage.html',
controller: 'StageCtrl'
}
}
The controllers associated are:
controller('StagesCtrl', function($scope,$http) {
$http.get("http://localhost/apistages")
.then(function(response) {
$scope.stages = response.data;
});
})
.controller('StageCtrl', function($scope, $http, $stateParams) {
$http({
method: 'GET',
url: 'http://localhost/apistage/',
params: {stageId: $stateParams.stageId}
}).then(function successCallback(response) {
$scope.stage = response.data;
}, function errorCallback(response) {
});
});
The stages list works well, but the query in the stage controller tries to access http://localhost/apistage/?stageId=43 which results in a 500 (Internal Server Error).
The URL format that I need to use is http://localhost/apistage/43 . How can I adjust the query to fetch that URL?
Then don't use params options on $http GET request. Instead just use simple string concatenation on URL while making call to service
$http({
method: 'GET',
url: 'http://localhost/apistage/'+$stateParams.stageId //append state parameter in URL itself
})
For REST API I'd highly recommend you to use ngResource($resource) module of angular. Which has good capability to deal with rest calls.
You should not use two controllers. Use only one controller and use $routeParams to get the url parameter. Here now you check if parameter is present or not and differentiate your logic as required. You can use the following code:
var stageId = $routeParams.stageId;
If(stageId)
Do something
else
Do something different

Angular async http request

I am trying to do a http ququest in angular. Somehow it seems am missing out on something which i cannot figure out what it is?
On Page load i get this error:
Error: [$injector:undef] http://errors.angularjs.org/1.4.5/$injector/undef?p0=%24formServices
My Service:
app.factory('$formServices',['$http','$q',function ($http, $q) {
function postSubmit (fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: { items: JSON.stringify(fData) }
});
}
}
]
);
And the controller that calls the service:
$formServices.postSubmit($scope.Parameters).then(function (response) {
console.log(response);
$scope.Results = response;
});
What am i missing out on?
$injector:undef
Try adding a return to your factory. Also, if you wish to call the function with dot notation you need to place the function inside of an object.
app.factory('$formServices',['$http','$q',function ($http, $q) {
return {
postSubmit: function(fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: { items: JSON.stringify(fData) }
});
}
}
}
]
);
Factory must return object from factory, so that will be exposed via to factory consumer via injecting its dependency.
Code
app.factory('$formServices', ['$http', '$q', function($http, $q) {
function postSubmit(fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: {
items: JSON.stringify(fData)
}
});
}
// should object
return {
postSubmit: postSubmit //link post submit to function
}
}]);
The issue is that your factory does not return an object. To learn more about this I suggest reading https://docs.angularjs.org/guide/providers
Evilzebra's answer would work I believe, but if you ever wanted to have more functionality in your factory, a good way to structure factories is:
app.factory('$formServices',['$http','$q',function ($http, $q) {
var service = {};
service.postSubmit = function (fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: { items: JSON.stringify(fData) }
});
}
return service;
}]);
This would allow you to add more features, appending them to the service object.

http post call not working from angularjs

I am new to AngularJS. I have included the code for the controller, service, and call to the rest service. Kindly advise why the call is not reaching the rest service.
My code is as follows:
app.config(function ($routeProvider) {
$routeProvider
.when('/addNewNote', {
controller: 'AddNewNoteController',
templateUrl:'views/addNote.html'
})
the angularjs controller is as below
app.controller('AddNewNoteController', ['$scope','savenote', function($scope,savenote) {
savenote.success(function(eData){
$scope.msg = eData;
The angular service to call the http post rest service
app.factory('savenote',['$http',function($scope,$http){
return $http({
method: 'POST',
url: <url is pasted here>,
dataType: 'json',
data: {
"title" : "123dddd",
"contents" : "123ddddtttttt"
},
headers: { 'Content-Type': 'application/json; charset=UTF-8' }
})
}]);
This is the rest service
#Path("/savenote")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public UserMessages saveNewNote(Note note) throws IOException {
.....
}
You forgot the type hint for $scope:
app.factory('savenote',['$scope', '$http', function($scope,$http){
Also, your factory should return an object with methods:
app.factory('savenote', ['$scope', '$http', function ($scope, $http) {
return {
save: function () {
return $http({
method: 'POST',
url: "<url is pasted here>",
dataType: 'json',
data: {
"title": "123dddd",
"contents": "123ddddtttttt"
},
headers: {'Content-Type': 'application/json; charset=UTF-8'}
});
}
};
}]);
And use it as follows:
savenote.send().then(function(eData) {});
Also, as #SarjanDesai stated in his comment, $scope is not used in your factory, so you should remove it.
savenote returning $http object which has then function for calling success and failure callback.
So update your controller function with below:
savenote.then(function successCallback(eData) {
$scope.msg = eData;
}
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.

Angular $resource JSON Callback not working - is this best practice?

I'm creating a resource to pass data into my controller for an existing api that need to hook into. I am not able to modify the back end unfortunately.
My Resource factory currently looks like this:
'use strict';
angular.module('XXX')
.factory('elements', function (
$resource
) {
return $resource('http://XXX/api/v1/elements/:id',
{
callback: 'JSON_CALLBACK',
id: '#id'
},
{
query: {
method: 'JSONP',
params: {
id: '#id'
}
},
all: {
method: 'JSONP',
params: {}
}
}
);
});
The elements.query() works fine, however the elements.all() does not work unfortunately. I did notice that in the returned content in my network tab, begins with angular.callbacks._2([{... DATA...}]) - this doesn't seem right to me.
UPDATE.....
OK so i've got it working with this:
angular.module('XXX')
.factory('element', function (
$resource
) {
return $resource('http://XXX/api/v1/elements/:id',
{
id: '#id',
callback : 'JSON_CALLBACK',
},
{
query: {
method: 'JSONP',
params: {
id: '#id'
}
},
all: {
method: 'JSONP',
isArray: true,
params: {
callback : 'JSON_CALLBACK',
}
}
}
);
});
however the json that it returns to the console comes in as an array.. I am able to parse it for use, but just wondering now if this is best practice?
That is the way isArray is meant for.
You need the isArray flag, because angular has to create an empty Object - in this case an Array - before the request is sent. So all bindings will work, because you have the same reference. At the time the result has arrived, it will be populated to your variable, the result object / array.
We are doing the service calls like this, maybe it will help you:
.factory('Person', function($resource, AppConfig) {
var Person = $resource(AppConfig.remoteURL + '/person/:id', {}, {
query: {method:'GET'},
queryAll: {method:'GET', isArray: true},
create: {method:'POST'},
update: {method: 'PUT'}});
return Person;
});
and call it like this:
Person.queryAll(function (result) {
angular.isArray(result); // should be true
}, function (error)
{
//doh!
}
You might want to specify a custom transformResponse to convert pull the data out of the array form.
Snippet from $resource docs:
transformResponse – {function(data, headersGetter)|Array.<function(data, headersGetter)>} – transform function or an array of such functions. The transform function takes the http response body and headers and returns its transformed (typically deserialized) version.
So your code would be something along the lines of:
all: {
method: 'JSONP',
isArray: true,
params: {
callback : 'JSON_CALLBACK',
},
transformResponse: function(data, headersGetter) {
return data.[....].DATA;
}
}
Usually, $resource is used for RESTful APIs. JSONP only uses GET.
So, I would use $http.JSONP instead of $resource for this.
In your code, can you let your server-side support CORS?

Categories