AngularJS app Crashing using parameter in $resource query() - angularjs

I made this simple factory returning a $resource:
app.factory('OusService', function ($resource,BASE_API) {
var res;
res = $resource(BASE_API+'/ou/:ouId',null,{
update: {
method: 'PUT' // this method issues a PUT request
}
});
return res;
});
Then I'm using that $resource in a controller called 'navCtrl' :
app.controller('navCtrl', ["$scope","$localStorage","OusService", function ($scope,$localStorage,OusService) {
var navOrg = $localStorage.navOrg;
OusService.query({ouId: navOrg.ou_id}).$promise.then(function(data){
console.log(data);
}, function(error) {
console.log(error);
});
}]);
That code is completely crashing but if I remove '{ouId: navOrg.ou_id}' the code is executed but the query doesn't contain the required parameter. I tried without a promise, with a callback, withtout a callback nor a promise. The code is always crashing with parameter.
I also tried defining default parameters in the factory.
Error :
TypeError: V is not a function
at http://10.0.0.145:8003/layout1/assets/js/app.min.js:34:14237
at forEach (http://10.0.0.145:8003/layout1/assets/js/app.min.js:10:14316)
at C.setUrlParams (http://10.0.0.145:8003/layout1/assets/js/app.min.js:34:14122)
at Function.l.(anonymous function) [as query] (http://10.0.0.145:8003/layout1/assets/js/app.min.js:34:12722)
at new <anonymous> (http://10.0.0.145:8003/layout1/assets/js/controllers/navCtrl.js:13:16)
at Object.invoke (http://10.0.0.145:8003/layout1/assets/js/app.min.js:11:16221)
at extend.instance (http://10.0.0.145:8003/layout1/assets/js/app.min.js:13:8182)
at nodeLinkFn (http://10.0.0.145:8003/layout1/assets/js/app.min.js:12:11139)
at compositeLinkFn (http://10.0.0.145:8003/layout1/assets/js/app.min.js:12:2680)
at http://10.0.0.145:8003/layout1/assets/js/app.min.js:12:1389 <nav data-ng-include=" 'assets/views/partials/nav.html' " class="ng-scope" data-ng-animate="1">
EDIT :
I updated angularjs from 1.5.7 to 1.5.11 and the problem has been resolved.
thank you

to use like this .. have you tried something like:
app.factory('OusService', function ($resource,BASE_API) {
var res;
res = $resource(BASE_API+'/ou/:ouId',{'#ouId':ouId},{
query: {
method: 'GET',isArray:true // or false if return an object
}
});
return res;
});
And then use it as you want
app.controller('navCtrl', ["$scope","$localStorage","OusService", function ($scope,$localStorage,OusService) {
var navOrg = $localStorage.navOrg;
OusService.query({ouId: navOrg.ou_id}).$promise.then(function(data){
console.log(data);
}, function(error) {
console.log(error);
});
}]);

I do not believe that the $resource query method accepts an argument. Rather, it returns an array of results. If you want to pass an id in I would suggest using get
OusService.get({ouId: navOrg.ou_id}).$promise.then(function(data){
console.log(data);
}, function(error) {
console.log(error);
});
Also, try updating your resource to the following:
app.factory('OusService', ['$resource', 'BASE_API',
function($resource, BASE_API) {
var res;
res = $resource(BASE_API + '/ou/:ouId', {ouId: #ouId}, {
update: {
method: 'PUT'
}
});
return res;
}
]);
The key changes to note being: {ouId: #ouId} as well as ['$resource', 'BASE_API',

Related

Error: $injector:undef Undefined Value in angularjs

The response of ajax is like ["99636941","74167247"]. But the values are not accepted by angularjs. The response is ok. If I declare the same response as static, then it is working properly.
app.factory("States", function(){
var states;
$.ajax({
url:'php/usersList.php',
type:'post',
success:function(data,status)
{
states = data;
console.log(states);
},
error:function(xhr,desc,err)
{
console.log(xhr);
console.log("Details: "+ desc + "\n error:"+err);
}
});
return states;
});
Couple of things to note:
Do not use jQuery ajax $.ajax in angularjs service - use $http instead as it will handle digest cycle by itself. Read: https://docs.angularjs.org/api/ng/service/$http
As you are making an ajax call, return states will get executed even before your ajax success event - try looking into Promises in javascript/angular js.
You may refactor this method like:
app.factory("States", function($http){
var getStates function(){
return $http.post('php/usersList.php');//ideally this should be a GET method
};
return {
getStates: getStates
}
});
And in theplace where you call this method:
var states;
States.getStates().then(function(data){
states = data;
})
If we make it more simpler, You can do it the following way.
app.factory("States", function($http){
var factory={};
factory.getStates=function($http){
return $http({
method:'GET',
url:'your URL'
});
};
/*similarly write as many functions as you need and then simply return the factory var*/
return factory;
});

I set the service data,but after $http done, I cannot get the service data

My service define like this:
module.factory('portfolio',function(){
var data;
var selectedPort;
return{
getData: function(){
return data;
},
setData:function(portfolios){
data = portfolios;
},
getSelectedPort:function(){
return selectedPort;
},
setSelectedPort:function(portfolioDetail){
selectedPort = portfolioDetail;
}
}
});
And in my controller the code as follows:
module.controller('portfoliosController', function($scope,$http, alertService,stockService, userDataService, portfolio){
var req = {
method: 'get',
url: 'www.facebook.com',
headers: {
'Authorization': userDataService.getToken()
}
};
$http(req).then(function(reponse){
$scope.portfoliosPriceList = reponse['data'];
portfolio.setData($scope.portfoliosPriceList);
console.log(portfolio.getData())//At here,I can get the portfolio's data
}, function(){
alertService.setMessge("System maintenance , please try again later");
alertService.alert();
});
console.log(portfolio.getData())//At here, I cannot get the portfolio's data
});
the error is
Error: undefined is not an object (evaluating 'message.substr')
Anybody can help me to solve this problem?Actually, I really do not understand, why I cannot get the data outside the $http
The request that you do with the $http service is done asynchronously, so the callback that you pass to the .send is not immediately invoked.
The code that follows (the console.log) is executed just after the $http(req) call is made but before the callback is called when the request is responded.
Maybe you will understand better with an simpler example:
function portfoliosController() {
var data = 'Initial Data. ',
content = document.getElementById('content');
// setTimeout would be your $http.send(req)
// calledLater would be your .then(function() { ... })
setTimeout(function calledLater() {
data = 'Data coming from the server takes some time to arrive...';
content.innerHTML = content.innerHTML + data;
}, 1000);
content.innerHTML = content.innerHTML + data;
}
portfoliosController();
<div id="content">
This is because javascript is asynchronous, so the code:
portfolio.getData()
Is maybe executing before the data is returned from the service.
In this case, you should only use the data of the portfolio just after the request is complete (inside the .then() function of $http) or put a promise.
Here is the documentation for angular promises:
https://docs.angularjs.org/api/ng/service/$q

String is not a function : Error AngularJS(factory) MongoDB

I am playing around with the MEAN stack. I have created a rest service to delete from mongo db which works fine but When I try to use angular Factory method and call it I get the above error
myApp.factory('methodFactory', ['$http', function ($http) {
return {
//id becomes undefined over here
removeContact:function($http, id){
//TODO add URL
var url = '/contactlist/'+id;
return $http({
method: 'DELETE',
url: url
});
}
};
}]);
myApp.controller('AppControl', ['$scope','$http','methodFactory', function($scope,$http,methodFactory) {
$scope.remove = function(id) {
console.log(id); //able to print correct id
methodFactory.removeContact(id).success(function(response){
console.log("remv"+response);
refresh();
});//tthiss throws the error
//this rest service works properly.
/*$http.delete('/contactlist/'+id).success(function(response){
console.log("remv"+response);
refresh();
});*/
};
};
This what node server looks like
app.delete('/contactlist/:id',function(req,res) {
var id = req.params.id;
console.log(id);
db.contactlist.remove({_id:mongojs.ObjectId(id)},function(err,doc){
res.json(doc);
});
console.log("exiting delete")
});
I am not sure if factory could be one of the way to call a rest service. What could cause the problem ?
Error
TypeError: string is not a function
at Object.removeContact (http://localhost:3000/controllers/controller.js:10:20)
at l.$scope.remove (http://localhost:3000/controllers/controller.js:85:23)
at hb.functionCall (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js:198:426)
at Cc.(anonymous function).compile.d.on.f (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js:215:74)
at l.$get.l.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js:126:193)
at l.$get.l.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js:126:419)
at HTMLButtonElement.<anonymous> (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js:215:126)
at HTMLButtonElement.c (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js:32:363)
Your removeContact method needs two parameters:
removeContact:function($http, id) ...
but you call it with only one:
methodFactory.removeContact(id) ...
Id is a string, I suppose, but it it will be assigned to the first parameter of the function $http, what must be executable according the code you provided.

HTTPInterceptor in AngularJS

We have APIs which returns errors inside the reponse XMLs instead of rejecting them and sending error responses.
So I have the following code to handle them,
$http({
url: apiURL,
method: "POST",
data: req,
headers: oHeaders,
dataType: "xml",
})
.success(function(data,status) {
console.log('success!!!!!');
deff.resolve(data);
})
.error(function(data,status) {
console.log('This is what I want to see!!!!!');
deff.reject(data);
});
myApp.factory('customHttpInterceptor', ['$q', function ($q) {
return function (promise) {
return promise.then(function (response) {
var parsed;
if (response.config.dataType == 'xml'){
parsed = $.xml2json(response.data);
if (parsed) {
angular.forEach(parsed, function(v, k) {
if (k == 'status') {
if (v.APIErrors) {
return $q.reject(response);
}
}
});
}
console.log(parsed);
}
return response;
}, function (errResponse) {
// do something on error
console.log('Error section in interceptor');
return $q.reject(errResponse);
});
};
}]);
What I expected to get from is that when an error is identified within the interceptor it will reject the promise and the control would get into the error section of the $http and log the "This is what I want to see!!!!!" message. But instead is show the "success!!!!!" message.
Is this the way it works or am I doing something wrong?
Ish
I see several things that seem wrong here :
Returning a result in forEach
angular.forEach(parsed, function(v, k) {
if (k == 'status') {
if (v.APIErrors) {
return $q.reject(response);
}
}
});
You probably wrote this because you're used to put return statements inside for loops. This does not work here, because you're returning from inside a function body. There is never any reason to return something in a forEach body function: this value is not going to be used by anything.
Angular Interceptor API
Maybe you just didn't show it in your code, but you have to register your interceptor.
$httpProvider.interceptors.push('customHttpInterceptor');
What's more, your interceptor does not have the correct form : in your case, it should be a object with a response method that returns a promise of a response from a response.

Hitting a REST-based Service With AngularJS Resource

I have an AngularJS app. In this app, I'm trying to ping a REST API. This API returns a list of orders.
I need to be able to handle the scenario where I successfully GET the orders. I also need to handle the
scenario where the request to GET the orders fails. In an attempt to do this, I'm using the ngResource
module. My controller looks like the following:
myController.js
myApp.controller('myController',
function myController($scope, myService) {
myService.getOrders(function(data) {
$scope.orders = data;
});
}
);
The definition of myService is stored in myService.js. That file looks like this:
app.factory("myyService", function($resource, $log) {
return {
getOrders: function(onSuccess) {
var orders = $resource("http://localhost:1000/orders", { fetch:{method:'JSON'} });
orders.fetch(function (response) {
console.log(response);
onSuccess(response.data);
});
}
};
});
When I run this code, I get a runtime error. The error says:
TypeError: Object function g(b){z(b||{},this)} has no method 'fetch'
Maybe there has to be something I don't understand. In my mind, I see fetch defined.
The other question I have is how do I set this up to handle failed requests? Like a 404 or 502?
You forgot the curly braces after the URL parameter...
Change: http://localhost:1000/orders", { fetch :
To: http://localhost:1000/orders", {}, { fetch :
app.factory("myyService", function($resource, $log) {
return {
getOrders: function(onSuccess) {
var orders = $resource("http://localhost:1000/orders", {}, { fetch : {method:'JSON'} });
orders.fetch(function (response) {
console.log(response);
onSuccess(response.data);
});
}
};
});
[EDIT]
To handle errors from the server side, you need to set the second function in the resource call.
Example :
orders.fetch(function success() {...},
function error() {... this will execute in a http error, 400 or 500}
);

Resources