ngResource retrive unique ID from POST response after $save() - javascript

So I have a Resource defined as follows:
angular.module('questionService', ['ngResource'])
.factory('QuestionService', function($http, $resource) {
var QuestionService = $resource('/api/questions/:key', {}, {
query: {
method:'GET',
isArray:true,
},
save: {
method: 'POST',
}
});
return QuestionService
});
And later on I take some form input and do the following
var newQ = {
txt: $scope.addTxt
};
QuestionService.save(newQ)
The server responds to the POST request both by reissuing the JSON for the object and setting the location header with the new unique ID. The problem is that Angular is not saving that returned JSON or the location header into the object and it is not getting set with the ID from the server for future operations. I've tried a number of things such as:
transformResponse: function(data, headersGetter) {
locationHeader = headersGetter().location;
key = locationHeader.split('/').slice(-1)[0];
data.key = key;
return data;
}
However the returned data item doesn't seem to be getting used. Am I missing something? This seems like a pretty common use case for interacting with a REST api.
Thanks!

You need to have a success handler to assign the new id to newQ manually:
QuestionService.save(newQ, function(data) {
newQ.id = data.id;
});
But there is a better to achieve the same. Because your QuestionService is a resource class object, you can instantiate your newQ like this:
var newQ = new QuestionService({text: $scope.addTxt});
Then, call $save() of newQ:
newQ.$save();
Now newQ should have the new id returned by the server.

I have Asp.Net server with WebApi2 running, i use Ok(number) to return content, and it return for example '6' as result. once it return, the angular show an object containing promise and state, and prototypes and a deep repeated hierarchy, but no value, no '6'.
So i went to see where the data goes, for seeing where the data is i define a transform, and i see awo the data, but it's not a json...
later i change it to following, and now i have a obj in my success function, which has sub property called 'returnValue' (as i defined), and this object hold my value.
transformResponse: function(data, header){
var obj={};
obj.returnValue=angular.fromJson(data);
return obj;
},

Related

Removing values from array and adding them to POST method request

I have a cart in my AngularJS app and I need to identify the items through their id through a POST method.
They are stored in an array called patent_ids and are appended to the request like so:
var cartArr = [];
var cartItems = ngCart.getItems()
cartItems.forEach(function(currentValue, index, array){
cartArr.push(currentValue._id)
})
var obj = {
patent_id: cartArr
};
fetchBasketPatents(obj);
function fetchBasketPatents(obj) {
//load of code to call service and pass the ids
}
var REST_SERVICE_URI = 'http://localhost:8080/p3sweb/rest-basket/';
factory.fetchBasketPatents = function(ids) {
var deferred = $q.defer();
$http.post(REST_SERVICE_URI, ids) //REQUEST TO BACK END WITH IDS
.then(
function(response){
deferred.resolve(response.data)
},
function(errResponse){
deferred.reject(errResponse)
}
)
return deferred.promise;
}
It works but it would be easier if rather than sending the ids in a named array, they could be sent as an anonymous array, or even better each item extracted an inserted into an anonymous object.
Question
How do I send the ids in the POST request in either an anonymous array or object? Apologies if I am missing something obvious.
How do I send the ids in the POST request in either an anonymous array or object?
From Document:
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
Where data – {string|Object}
So the answer is: you cannot define anonymous array but object only (like you did)

AngularJs http request concats my data into a JSON key

Sometimes a behavior is so bizarre that I don't even know how to begin to google it. I'm fairly new at Angular, and I am trying to send POST data to my node server from the client. Here is the controller on the client side:
var app = angular.module("groomer", []);
app.controller("gCtrl", function($scope, $http) {
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$scope.send = function() {
$http({
method : "POST",
url : "/gUpdate",
data: {
gName:$scope.gName,
gPhone:$scope.gPhone,
gWebsite:$scope.gWebsite,
gEmail:$scope.gEmail,
gCustAcct:$scope.gCustAcct,
gAddress:$scope.gAddress,
gNotes:$scope.gNotes
}
}).then(function success(response) {
alert(console.log('Success!'));
}, function error(response) {
alert(console.log('Booooooo'));
});
};
});
What I naively imagine ought to show up at the server is:
req.body = {
gName:'a',
gPhone:'b',
gWebsite:'c',
gEmail:'d',
gCustAcct:'e',
gAddress:'f',
gNotes:'g'
}
But things get weird. What actually shows up at the server as the request body is:
{"{\"gName\":\"a\",\"gPhone\":\"b\",\"gWebsite\":\"c\",\"gEmail\":\"d\",\"gCustAcct\":\"e\",\"gAddress\":\"f\",\"gNotes\":\"g\"}":""}
In case it takes you a second to see what's happening here, that's all of my JSON keys and data in an object, double-quoted, escaped, concatenated as a string, and passed to the server inside an object as a JSON key corresponding to an empty value.
//so
var lifeMakesSense = {gName:'a',gPhone:'b',gWebsite:'c',gEmail:'d',gCustAcct:'e',gAddress:'f',gNotes:'g'}
//becomes
var waitNo = "{\"gName\":\"a\",\"gPhone\":\"b\",\"gWebsite\":\"c\",\"gEmail\":\"d\",\"gCustAcct\":\"e\",\"gAddress\":\"f\",\"gNotes\":\"g\"}"
//then
var whatEven = {waitNo:""} // nailed it
Thoughts?

Restful call from angular is not returning results

Here am trying to make a RESTful call to an external API.
am trying to achieve 2 things in one call. So, I have one function with 2 nested functions within.
The first one calls the search API to search for a product.
The second one calls recommended API to retrieve recommendations based on the results from the first one.
My AngularJS Code is as follow;
var walmartAssn= angular.module('myApp', ['ngResource']);
walmartAssn.controller('walmartAssnController', function($scope,$resource) {
//define the API urls
var urlSearchProductApi= 'http://api.walmartlabs.com/v1/search';
var urlRecProductApi='http://api.walmartlabs.com/v1/nbp';
//define API key
var keyApi='exampleKey123';
$scope.searchProductMethod= function(){
//pass the value from the user input text box
$scope.searchItem = $scope.item ;
$scope.productId;
//get the data from the Walmart product search API
searchRequest = $resource(urlSearchProductApi, { callback:
"JSON_CALLBACK" }, { get: { method: "JSONP" }});
//pass the input text as a parameter through a GET request
$scope.searchedProducts = searchRequest.get({ apiKey: keyApi,
query: $scope.searchItem });
console.log($scope.searchedProducts.$promise);
$scope.searchedProducts.$promise.then(function(eventDetail){
//fetch the ID of the first item
$scope.productId = eventDetail.items[0].itemId;
});
recommendRequest = $resource(urlRecProductApi, { callback:
"JSON_CALLBACK" }, { get: { method: "JSONP" , isArray:true}});
console.log(recommendRequest);
$scope.recommendedProducts = recommendRequest.get({ apiKey:
keyApi, itemId: 42608121 });
console.log($scope.recommendedProducts)
$scope.recommendedProducts.$promise.then(function(){
$scope.recommendedProductsList = eventDetail;
console.log("Print recommended list");
console.log(eventDetail);
console.log($scope.recommendedProductsList);
console.log('End');
});
} });
In the above app, the first function returns result while the second function does not.
In chrome console am getting the following, not the fist function returns an array of JSONs while the second one was blocked.
While on the Network tab in the chrome console, i see the the call was successful, as in shown below;
Moreover, I have tried the URL with hard coded values in the browser and worked successfully.
Any help is appreciated, thanks in advance.
Assuming that the 2nd call does not depend on the first, I see that you are not defining eventDetail as an argument to the second method.
So, instead of:
$scope.recommendedProducts.$promise.then(function(){
It would be:
$scope.recommendedProducts.$promise.then(function(eventDetail){
If you actually mean to use the eventDetail from the first method (the one used with $scope.searchedProducts.$promise), then the whole second request code needs to be called from the first then handler, passing the data needed.
Something like:
var walmartAssn= angular.module('myApp', ['ngResource']);
walmartAssn.controller('walmartAssnController', function($scope,$resource) {
//define the API urls
var urlSearchProductApi= 'http://api.walmartlabs.com/v1/search';
var urlRecProductApi='http://api.walmartlabs.com/v1/nbp';
//define API key
var keyApi='exampleKey123';
$scope.recommend = function(itemId) {
var recommendRequest = $resource(urlRecProductApi, { callback:
"JSON_CALLBACK" }, { get: { method: "JSONP" , isArray:true}});
console.log(recommendRequest);
$scope.recommendedProducts = recommendRequest.get({ apiKey:
keyApi, itemId: itemId });
console.log($scope.recommendedProducts);
$scope.recommendedProducts.$promise.then(function(eventDetail){
$scope.recommendedProductsList = eventDetail.items; // or just `eventDetail`?
console.log("Print recommended list");
console.log(eventDetail);
console.log($scope.recommendedProductsList);
console.log('End');
});
};
$scope.searchProductMethod= function(){
//pass the value from the user input text box
$scope.searchItem = $scope.item ;
$scope.productId;
//get the data from the Walmart product search API
var searchRequest = $resource(urlSearchProductApi, { callback:
"JSON_CALLBACK" }, { get: { method: "JSONP" }});
//pass the input text as a parameter through a GET request
$scope.searchedProducts = searchRequest.get({ apiKey: keyApi,
query: $scope.searchItem });
console.log($scope.searchedProducts.$promise);
$scope.searchedProducts.$promise.then(function(eventDetail){
//fetch the ID of the first item
$scope.productId = eventDetail.items[0].itemId;
$scope.recommend($scope.productId);
});
};
});
One more thing:
Why is isArray:true used only in recommendation but not in search?
Update
It might be worth trying a jQuery JSONP call to see if it works. Maybe the recommendation endpoint does not support JSONP. AngularJS returns 404 in this case according to https://stackoverflow.com/a/24893912/146656

pass collection of objects through http post in angular js

I have pass a collection of objects through http post in angular js.
The code is as follows:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data.ContentId, { Selected: true }); // I could able to get all the selected objects here, No problem with it
var jsonData = angular.toJson(contents); //It is not able to convert to Json if there are more than 5 records
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent?jsonData=' + jsonData, {});
promise.success(function () {
window.location.reload();
});
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(string jsonData)
{
var contents = JsonConvert.DeserializeObject<List<ContentNodeInWorkFlow>>(jsonData);
foreach (var content in contents)
{
_contentService.PublishContent(content.ContentId, userId);
}
}
}
The above code works fine if there are 5 records or less. If there are more records, I could able to get all the selected record
objects in the variable 'contents'. But the problem is occuring when converting to Json for all those objects. I
have about 500 records to pass through. How can do I it?
There is no specific reason to convert to JSON data. I just need to extract the ids of all the selected items. I have modified the above code as below:
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var abc = [];
angular.forEach(contents, function(content)
{
abc.push(content.ContentId); // got all the ids in the array now
});
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,{contents : abc});
promise.success(function () {
window.location.reload();
});
}
I have just took an array and pushed all the content ids into it. I could able to see all the ids in the array now. I tried to pass the array as above.
How to retrieve those array in the code behind.
[ReferrerFilterAttribute]
[HttpPost]
[System.Web.Http.ActionName("CmsPublishApprovedContent")]
public void CmsPublishApprovedContent(int[] abc)
{}
I do not see any values obtained under int[] abc. What will be the datatype for the parameter in the method call above.
You need second argument of $http.post method. You have to send such data by POST requests, not in query of url. You can put some data into body of the post request.
You need this:
var postBodyWithHugeAmountOFData = {data: [1,2,3,4,5...500]};
$http.post(url, postBodyWithHugeAmountOFData).success(function () {});
Also, you must be ready to handle this request in your backend.
is there any specific reason u want to pass this data as a JSON?.
if u r using Web API in that case u can pass the object as it is but only make sure that collection in web API method contains all the property in javascript collection
Thank you for all your posts. It's working fine without converting to Json. The code is as below.
$scope.selectedContent = function () {
var contents = $filter('filter')($scope.data, { Selected: true });
var promise = $http.post('/webapi/cmsApi/CmsPublishApprovedContent' ,contents);
promise.success(function () {
window.location.reload();
});
}
and the signature would be
public void CmsPublishApprovedContent(List<ContentNodeInWorkFlow> abc)
{
}

Vue.js is corrupting data when setting an array

So I'm getting json response from my controller, which looks simply like:
return Plan::find($request->id)->toJson();
And when I'm setting the received data into the vue array, some data get corrupted, dates are being changed randomly (for exmaple, start date and end date become the same, but the network response is correct).
I found out that the problem is with vue.js that I'm using to control data. for now, the vue method that gets data looks as follows:
updatePlan: function(id) {
var json;
$.getJSON('{{action("Controller#getJSON")}}',{id}).success(function(data) {
{plan: id}).success(function(data) {
json=data;
animatedOpenModal('edit-button','editPlanModal');
});
setTimeout(function(){
console.log(json);
//vm.setPlan(json);
},100);
},
and the commented method is
setPlan: function(json) {
vm.$set('current_edit_plan', json);
console.log(vm.current_edit_plan);
},
and for now console.log(json) shows correct data, but if I remove // - everything will fall apart: dates will become incorrect in both console logs and in array itself.
What is this and how could it be solved? I would highly appreciate any possible help!
Try this:
updatePlan: function(id) {
var self = this;
var json;
$.getJSON('{{action("Controller#getJSON")}}',{id}).success(function(data) {
{plan: id}).success(function(data) {
json = data;
animatedOpenModal('edit-button','editPlanModal');
});
setTimeout(function(){
console.log(json);
self.setPlan(json);
},100);
},
Then for your setPlan method:
setPlan: function(json) {
this.current_edit_plan = json;
console.log(this.current_edit_plan);
},

Categories

Resources