Query: Response does not match configured parameter - angularjs

i am getting response error please any one try to solve my problem. i am trying to solve that but i didn't solve this. please help me.
thanks in advance
$scope.init = {};
var Call = $resource('../api/Home', {}, { query: { method: 'POST', isArray: false} });
$scope.init = function () {
//alert("hi");
$scope.selected = "";
var x = $('#txtSearch').val();
var _ReqObj = new Object();
_ReqObj.id = x;
_ReqObj.Meth = "GJ";
Call.query({}, _ReqObj,
function (response) {
alert(response);
alert(_ReqObj);
if (response == '') {
// alert('no data');
window.location.replace("index.html");
}
else {
//$scope.click = response;
$scope.init = response;
}
},
function (error) {
window.location.replace("index.html");
}
);
};

The error message says: "Expected response to contain an object but got an array"
this means: Your request (Call.query) does expect a single object (you are setting isArray: false). But the server sends an array. So the server is not sending what the function expects!
There is some hints I want to give you:
Why are you using query? A query is normally used to get an array from the server, not a single object. Why are you using query at all?
Do you really want a single object or do you want a list of objects?
What is the server sending? Open the development console in your browser (ctr+alt+I in Chrome) and click on the Network tab. Click on the request (../api/Home) and check the response from the server. You should see the json objects or arrays the server sent as a response to your request.

Related

How to display JSON data in angularjs success function?

Hi I am developing Angularjs application and getting some data from Web API. I am able to receive data. I can confirm this because i can see in fiddler and browser developer tool as well. Below is my code. I am returning data as json from web api. I am returning below object.
return Request.CreateResponse(HttpStatusCode.OK, obj);
Object obj contains some fields(data);
In browser i can see response as below.
{"ID":11,"project_id":1,"levels":1,"icon":1,"description":1,"summary":1,"output":1,"owner":1,"role":1,"objectives":1,"reporting":1,"performance_indicators":1,"success":0,"Created":"0001-01-01T00:00:00","Updated":"0001-01-01T00:00:00"}
This is my angular code.
var saveSubs = ProjectSetting_Service.AddProcessSettings(sub);
saveSubs.then(function (data) {
alert((data.data));
alert((data.obj));
}, function (error) {
})
This is my service.js code
this.AddProcessSettings = function (sub) {
$http.post('/api/NCT_ProcessSettings/', sub).success(function (response) { alert(response); });
}
In alert i want to see response data. May i get some help? Any help would be appreciated. Thank you.
According your response, it does not have data in it,
just put the alert as,
var saveSubs = ProjectSetting_Service.AddProcessSettings(sub);
saveSubs.then(function (data) {
alert((data));
alert((data.project_id));
}, function (error) {
})
UPDATE
Your services is not returning anything, just change the service response to return it,
then you can access the data like alert(data.data);

AngularJS : $resource, response Object or Array [duplicate]

There are two ways I can GET a REST resource by ID:
GET /users/1
GET /users/1,2
The first returns a single object like {id:1,name:"John"} while the second returns an array like [{id:1,name:"John"},{id:2,name:"Jill"}].
Please, no arguments about whether or not this is legit REST; just accept that a service has this and I need to work with it.
angular's $resource actually intelligently handles it from the request side:
User.get({users:['1','2']})
transforms into
GET /users/1,2
But it doesn't handle the response well. It expects a single object. If I change the definition to isArray:true, then it fails on a single request GET /users/1
How do I get it to intelligently handle both?
EDIT: I did some weird hacking to get it to work, but would prefer a native method:
factory('Resource',['$resource','_',function ($resource,_) {
return function(url,params,methods){
var defaults = {
getSingle: {method: 'get', isArray:false},
getMultiple: {method: 'get', isArray:true}
}, resource = $resource(url,params,angular.extend(defaults,methods)), urlParams = {};
_.each(url.split(/\W/), function(param){
if (param && (new RegExp("(^|[^\\\\]):" + param + "\\W").test(url))) {
urlParams[param] = true;
}
});
// do not override if they did
if (!(methods||{}).get) {
resource.get = function (params,success,error) {
// look for multiples
var isMultiple = false;
_.each(params,function (val,key) {
if (key && urlParams[key] && angular.isArray(val)) {
isMultiple = true;
return(false);
}
});
return this[isMultiple?"getMultiple":"getSingle"](params,success,error);
};
}
return(resource);
};
}]).
The normal convention is to create a Resource.get() method for single objects, and a Resource.query() method for arrays of them.
I had a similar issue with the WP-API when trying to do a PUT request to a post. Currently that API returns an object representing the post if everything went okay, but if there is an error (eg the authorization credentials don't match) then it returns an array of errors. So I was getting the error Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array.
I managed to find a solution by using the transformResponse property on my custom action object. I define a function which inspects the response and then if it is an array, it converts the array into an object. This seems to work okay, and seems a bit less complex than the solution you posted in your update:
var wpPost = $resource(PATH_TO_WORDPRESS_API + 'posts/:id', {},
{
'update': {
method: 'PUT',
params: {id: '#id'},
transformResponse: function(data) {
var response = angular.fromJson(data);
if (response.length) {
// the response is an array, so convert it into an object
var object = {};
for( var i = 0; i < response.length; i ++) {
object[i] = response[i];
}
return object;
} else {
return response;
}
}
}
});

Generate pdf using stream in Angular

I am trying to generate pdf and display inside any Div, I am getting binary data from server but when I try to convert that stream it says failed to load pdf.
I googled it and saw response of many people saying use responseType: 'arraybuffer' but I am getting object from server and extracting binary from it so I can't use it, though I tried with this approach as well but it didn't work.
Here is my controller code:
correspondenceService.getCorrespondenceDocument(id).$promise.then(function (data) {
var file = new Blob([(data[0].documentBytes)], { type: 'application/pdf' });
var fileURL = window.URL.createObjectURL(file);
vm.content = $sce.trustAsResourceUrl(fileURL);
window.open(fileURL);
}, function (reason) { });
}
This is Service:
getCorrespondenceDocument: function (correspondenceId) {
return $resource(correspondenceUrl + "getCorrespondenceDocuments").query({ correspondenceId: correspondenceId });
}
and this is my webApi:
[Route("getCorrespondenceDocuments")]
[HttpGet]
public async Task<IEnumerable<Document>> GetCorrespondenceDocumentsAsync(int correspondenceId)
{
var documents = await _correspondenceFacade.GetCorrespondenceDocumentDetailsAsync(correspondenceId);
return Mapper.Map<IEnumerable<Document>>(documents);
}
Trying to display like this on View:
Please let me know where I am doing mistake. Many thanks in advance.
Regards,
Vivek
Finally I managed to do it. Problem is I was passing 3 parameters in $http.get(), now I am passing 2 parameters only.
getCorrespondenceDocuments: function (correspondenceId) {
return $http.get(correspondenceUrl + 'getCorrespondenceDocuments' + '?correspondenceId=' + correspondenceId, { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
Though I don't like to pass any parameter using this "?" and specifying id but I couldn't find any solution to this problem.
Many thanks guys for going through my post.
Regards,
Vivek

AngularJS reload data after PUT request

Should be a fairly easy one here for anyone who knows Angular. I am trying to update the data that is displayed after I make a PUT request to update the object. Here is some code:
Post service (services/post.js)
'use strict';
angular.module('hackaboxApp')
.factory('Post', function($resource) {
return $resource('/api/posts/:id', {id : '#id'}, {
'update': { method: 'PUT' }
})
});
Server side controller function that gets executed when trying to update data (lib/controllers/api.js)
exports.editsave = function(req, res, next) {
var posty = req.body;
console.log(posty._id.toString() + " this is posty");
function callback (err, numAffected) {
console.log(err + " " + numAffected);
if(!err) {
res.send(200);
//res.redirect('/forum');
}
}
Post.update(posty, { id: posty._id.toString() }, callback);
};
This is the console output for the above code:
53c54a0d4960ddc11495d7d7 this is posty
null 0
So as you can see, it isn't affecting any of the MongoDB documents, but it also isn't producing errors.
This is what happens on the client (Angular) side when a post is updated:
$scope.saveedit = function() {
console.log($scope.post._id + " post id");
// Now call update passing in the ID first then the object you are updating
Post.update({ id:$scope.post._id }, $scope.post, function() {$location.path('/forum')});
};
After the redirect, $location.path('/forum'), none of the data is displayed as being updated...when I look in the database...nothing has changed either...it is like I am missing the step to save the changes...but I thought that update (a PUT request) would do that for me.
I use ng-init="loadposts()" when the /forum route is loaded:
$scope.loadposts = function() {
$http.get('/api/posts').success(function (data) {$scope.posts = data});
};
Shouldn't all the new data be loaded after this? Any help would be appreciated. Thanks!
Your server side output indicate that the update query doesn't match any document in the database.
I'm guessing that you are using Mongoose in NodeJS server side code to connect to mongodb.
If that the case, your update statement seems incorrect.
Instead of { id: .. } it should be { _id: .. }
Also the conditions object and updated object are swapped.
The statement should be like this:
Post.update({ _id: posty._id.toString() }, posty, callback);
If you are not using Mongoose, please eloborate more on which library you are using or better than that, show the code where the Post variable is defined in your server side code.
Ok I got it.
the problem is that you are not using the Angular resource api correct.
This code need to be changed:
$scope.saveedit = function() {
console.log($scope.post._id + " post id");
Post.update({ id:$scope.post._id }, $scope.post, function() {$location.path('/forum')});
};
Into:
// Update existing Post
$scope.saveedit = function() {
var editedpost = new Post($scope.post); //New post object
editedpost.$update(function() {
$location.path('/forum');
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
And as for the server code (taken from my own working module):
exports.update = function (req, res) {
var post == req.post;
post = _.extend(post, req.body);
post.save(function (err) {
if (err) {
return res.send(400, {
message: getErrorMessage(err)
});
} else {
res.jsonp(post);
}
});
};

Can Angular $resource.get handle both array and non-array for GET?

There are two ways I can GET a REST resource by ID:
GET /users/1
GET /users/1,2
The first returns a single object like {id:1,name:"John"} while the second returns an array like [{id:1,name:"John"},{id:2,name:"Jill"}].
Please, no arguments about whether or not this is legit REST; just accept that a service has this and I need to work with it.
angular's $resource actually intelligently handles it from the request side:
User.get({users:['1','2']})
transforms into
GET /users/1,2
But it doesn't handle the response well. It expects a single object. If I change the definition to isArray:true, then it fails on a single request GET /users/1
How do I get it to intelligently handle both?
EDIT: I did some weird hacking to get it to work, but would prefer a native method:
factory('Resource',['$resource','_',function ($resource,_) {
return function(url,params,methods){
var defaults = {
getSingle: {method: 'get', isArray:false},
getMultiple: {method: 'get', isArray:true}
}, resource = $resource(url,params,angular.extend(defaults,methods)), urlParams = {};
_.each(url.split(/\W/), function(param){
if (param && (new RegExp("(^|[^\\\\]):" + param + "\\W").test(url))) {
urlParams[param] = true;
}
});
// do not override if they did
if (!(methods||{}).get) {
resource.get = function (params,success,error) {
// look for multiples
var isMultiple = false;
_.each(params,function (val,key) {
if (key && urlParams[key] && angular.isArray(val)) {
isMultiple = true;
return(false);
}
});
return this[isMultiple?"getMultiple":"getSingle"](params,success,error);
};
}
return(resource);
};
}]).
The normal convention is to create a Resource.get() method for single objects, and a Resource.query() method for arrays of them.
I had a similar issue with the WP-API when trying to do a PUT request to a post. Currently that API returns an object representing the post if everything went okay, but if there is an error (eg the authorization credentials don't match) then it returns an array of errors. So I was getting the error Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array.
I managed to find a solution by using the transformResponse property on my custom action object. I define a function which inspects the response and then if it is an array, it converts the array into an object. This seems to work okay, and seems a bit less complex than the solution you posted in your update:
var wpPost = $resource(PATH_TO_WORDPRESS_API + 'posts/:id', {},
{
'update': {
method: 'PUT',
params: {id: '#id'},
transformResponse: function(data) {
var response = angular.fromJson(data);
if (response.length) {
// the response is an array, so convert it into an object
var object = {};
for( var i = 0; i < response.length; i ++) {
object[i] = response[i];
}
return object;
} else {
return response;
}
}
}
});

Resources