Angular POST method send only a JSON array - json

I have an Angular frontend which communicates with a Spring REST API. The Spring endpoint expects a JSON array, but with Angular HttpClient POST method I don't know how to send only a JSON array. Now I get HTTP error code 400 (Bad request).
What I need to send to the endpoint (this is tested and works in an API tester):
[
{
"date": "2020-05-26T02:00:00.000Z",
"blocked": false,
"reservation": null
},
{
"date": "2020-05-27T00:00:00.000Z",
"blocked": true,
"reservation": null
}
]
The way I'm sending the changes now:
modifyElements(id: number, elements: Element[]): Observable<Element[]> {
return this.http.post<Element[]>(this.baseUrl + '/modify/' + id, elements);
}
The structure of the data that is sent by HttpClient's put method is below:
{
"0": {
"date": "2020-05-26T02:00:00.000Z",
"blocked": false,
"reservation": null
},
"1": {
"date": "2020-05-27T00:00:00.000Z",
"blocked": true,
"reservation": null
}
}
What I also tried and is closer to what I need:
this.http.post<Element[]>(this.baseUrl + '/modify/' + id, {elements: elements});
What this sends:
"elements": [
{
"date": "2020-05-26T02:00:00.000Z",
"blocked": false,
"reservation": null
},
{
"date": "2020-05-27T00:00:00.000Z",
"blocked": true,
"reservation": null
}
]
This is still not accepted by the API, results in the same error.
Please help me how can I send the data in the right structure, only a JSON array.
I already know how can I workaround this issue in Spring: in the controller method expecting for a request body of a new class that has just one member which is a collection, but that's not a nice solution.
I would like to know how it can be done without a workaround, on the Angular side.
Edit:
Thank you for the answers so far, but they return the same array I had, with the same structure.
The data structures I inserted in the question are the request bodies sent by Angular's HttpClient, copied from Chrome DevTools.
I think the problem is not with my original array, but with how HttpClient creates the JSON that it sends.
It seems to me that it can't interpret an array as a simple JSON array, and can only send a JSON array as a key-value pair, the value being the JSON array.
What I need instead is to get rid of the key and send only the plain value.
The question is, can HttpClient do that?

I faced the same problem, and I resolved with:
return this.http.request<ReturnType>(
'POST',
URL,
{
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
body: JSON.stringify(array)
});

Use this snippet
modifyElements(id: number, elements: Element[]): Observable<Element[]> {
const elementsArray = Object.assign([], elements);
return this.http.post<Element[]>(this.baseUrl + '/modify/' + id, elementsArray );
}
This will convert to the required format
var a ={
"0": {
"date": "2020-05-26T02:00:00.000Z",
"blocked": false,
"reservation": null
},
"1": {
"date": "2020-05-27T00:00:00.000Z",
"blocked": true,
"reservation": null
}
}
var c = Object.assign([], a)
console.log(c)

as I see you have object type [key:value] ,key is index value is an element entity. you have to extract values from this object and then send it to the server
Object.values(elements) //send this

Related

Get only one item from the array response in the Postman body using json

I am very new to Postman and have a method in my API taking in 2 params: AccountNumber and GroupId to check if there's a customer Id associated with the AccountNumber. When I run the Post request, if it returns 2 or more customerIds, I'm supposed to return the response to the user to pick which customerId to use. How do I do that?
Right now, in the body of the request, I have:
{
"AccountNumber":"0001",
"GroupId": "1"
}
The output is an array of customerId. How do I test with only one customerId picked from the POST response?
Thank you for your help, I really appreciate it!
It's unlikely to be a Postman issue.
You are consuming the API through Postman. You are not able to control the output of the API itself from Postman.
What you can do, though, is write a test case for the current request. There is a 'Tests' tab, where the 'Params' tab is. At the right, there are snippets on how to create the test with response body. Let me give you a simple test case to get the first element:
Let's say I have the following response body
[
{
"name": "Blue",
"id": "5f1830d217afbb52acac9868"
},
{
"name": "Orange",
"id": "5f1e7afeb334ae70b4f05d1d"
},
{
"name": "Red",
"id": "5f1e7b10b334ae70b4f05d1e"
},
{
"name": "Green",
"id": "5f1e7b10b334ae70b4f05d1f"
},
{
"name": "Yellow",
"id": "5f1e7b10b334ae70b4f05d20"
}
]
The test case would look like this:
pm.test("Example Test", function () {
var jsonData = pm.response.json();
pm.expect(jsonData[0]).to.eql({
name: "Blue",
id: "5f1830d217afbb52acac9868"
});
});

Microsoft.Graph Unable to deserialize the response

I am quite new to programming and especially Microsoft.Graph
I am having problems handling the response to:
https://graph.microsoft.com/v1.0/me/drive/root/children
the response looks like this (just much longer):
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('xyz%40hotmail.com')/drive/root/children",
"value": [
{
"createdBy": {
"user": {
"displayName": "xyz",
"id": "cf58e4781082"
}
},
"createdDateTime": "2009-01-08T08:52:07.063Z",
"cTag": "adDpFREJDR4RTQMTgxMDgyITEyOC42MzYxODM0MTU0Mjc3MDAwMDA",
"eTag": "aRURCQ0Y1OEU0A4MiExMjguMA",
"id": "EDBCF58E471082!128",
"lastModifiedBy": {
"user": {
"displayName": "xyz",
"id": "edbcf58e48082"
}
}, ............. etc...
The response that I received is correct, in JSON format (I believe ><), but I cannot figure out how to parse it into an array containing the folders name.
Please help!
Have considered using the Microsoft Graph client library? It will deserialize the JSON. Your call will look like this:
// Return all children files and folders off the drive root.
var driveItems = await graphClient.Me.Drive
.Root
.Children
.Request()
.GetAsync();
foreach (var item in driveItems)
{
// Get your item information
}
Here's some samples to help you get started:
https://github.com/microsoftgraph?utf8=%E2%9C%93&q=csharp
You can use the JavaScriptSerializer to do this. Assuming
//json contains the JSON Response
var jsonOutput = new System.Web.Script.Serialization.JavaScriptSerializer();
jsonOutput.DeserializeObject(json);
This has been discussed earlier. See this thread: Easiest way to parse JSON response
Refer this link for JavaScriptSerializer: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx

Removing back Slash from JSON in angularjs

I am getting a JSON object from a webservice which after JSON.stringify().I am getting this output-`
[
{
"user": "A220",
"shorttext": "shanghai",
"reportedBy": "S,A",
"questions": "[{\"question\":\"Q1\",\"is_mand\":\"0\",\"type\":\"text\",\"answer\":\"w\",\"ansYesOrNo\":false,\"ansDetails\":\"\"},{\"question\":\"Q2\",\"is_mand\":\"0\",\"type\":\"text\",\"answer\":\"ed\",\"ansYesOrNo\":false,\"ansDetails\":\"\"}]",
"notifno": "20143995",
"error": "",
"createdOn": "2015-09-09 13:08:36",
"Id": 0,
"$$hashKey": "object:89"
}
]
`
I want to remove all these back slash.
I tried using
var a=JSON.stringify(<that object>).replace(/\\/g, "");
But its giving result as a form string that too INVALID like this-
[
{
"user": "A220",
"shorttext": "shanghai",
"reportedBy": "S,A",
"questions": "[{"question":"Q1","is_mand":"0","type":"text","answer":"w","ansYesOrNo":false,"ansDetails":""},{"question":"Q2","is_mand":"0","type":"text","answer":"ed","ansYesOrNo":false,"ansDetails":""}]",
"notifno": "20143995",
"error": "",
"createdOn": "2015-09-09 13:08:36",
"Id": 0,
"$$hashKey": "object:89"
}
]
My only objective is to remove the back slash without changing the data type.
I want to access the first question of questions.
Its not working...
JsFiddle link-LINK
You dont need to do JSON.stringify() in web service response. You can directly work like
$http.get('/someUrl').
then(function(response)
{
$scope.data = response;
},
function(response)
{
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Now you have print in html like {{data}}
You can use this method to remove backslash from a JSON string
var data = {"\\id\\":"\\23232\\","\\pass\\":"\\1434\\"};
console.log(data);
var b=JSON.stringify(data);
str = b.replace(/\\/g, '');
console.log(str);

Posting data in a JSON file in AngularJS - (using django REST here to create that JSON file.)

I am using AngularJS along with Python & Django and Django REST API.
There is a JSON file created by the REST API and I need to post data into it using Angular $http.post().
I need to know if it is possible or not.
Im majorly getting 403(Forbidden) and 400(BAD REQUEST) errors on post..
$http({
method: 'POST',
url: '<JSON FILE URL>',
data: $scope.tmpDataSet,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}});
This is my .post() method. where im fetching the data from a form made in angular and storing it in 'tmpDataSet'. Its being created properly and im able to store into the array.
Im just not able to write it into the JSON file.
The structure of my JSON file is
{
"count": 6,
"next": null,
"previous": null,
"results": [
{
"name": "fff",
"mobile_no": "fff",
"email": "n#gmail.com",
"message": "dfdf",
"id": 1
},
{
"name": "asd",
"mobile_no": "0987654321",
"email": "asd#gmail.com",
"message": "no",
"id": 2
}
]
If any more code detail is needed please comment.
This issue was solved by adding CSRF tokens to the angular app and using the regular $http.post() function with all the parameters.
app.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});
and,
$http.post('<URL>', item).error(function(data,status,headers,config){
console.log('COULDNT POST!');
}).success(function(data, status, headers, config){
console.log('POSTED!');
});

Removing excess comma on JSON Object

Currently been working on eliminating the excess "," comma on the json object I have below.
{"rules": {
"1000": {
"action": "2",
"category": "skype",
"entity": "Private",
"id": "1000",
},
"1200": {
"action": "2",
"category": "http",
"entity": "Public",
"id": "1200",
},
"100": {
"action": "2",
"category": "ftp",
"entity": "Public",
"id": "100",
},
"0": {
"entity": "Private",
"category": "alcohol, tobacco",
"action": "1",
"id": "low",
},
"3000": {
} }}
Maybe you have some insights on what's the cleanest way to eliminate it using AngularJS.
The data was parsed from this code snippet.
var request = {
url: 'sample/uri',
method: "GET",
transformResponse: specialTransform
};
var response = $q.defer( );
$http( request ).success( function( THIS DATA -> data, status ) {
eval
var fixTrailingCommas = function (jsonString) {
var jsonObj;
eval('jsonObj = ' + jsonString);
return JSON.stringify(jsonObj);
};
fixTrailingCommas('{"rules": { "1000": { "action": "2", "category": "skype", "entity": "Private", "id": "1000" , } } }');
Please use eval here only if you completely trust incoming json, and also be aware of other eval evils as described on MDN and its note on JSON parsing
Note that since JSON syntax is limited compared to JavaScript syntax, many valid JavaScript literals will not parse as JSON. For example, trailing commas are not allowed in JSON, and property names (keys) in object literals must be enclosed in quotes. Be sure to use a JSON serializer to generate strings that will be later parsed as JSON.
You may also choose to rely on implementation of JSON2 by Douglas Crockford which uses eval internally
On current browsers, this file does nothing,
preferring the built-in JSON object. There is no reason to use this file unless
fate compels you to support IE8, which is something that no one should ever
have to do again.
But because we really need to use this library, we have to make few code modifications, e.g. simply comment out JSON type check, which will then override native browser object (or we may also introduce new JSON2 global variable)
//if (typeof JSON !== 'object') {
JSON = {};
//}
P.S. Other parsing fuctions json_parse.js and json_parse_state.js, which don't use eval, throw a syntax error
Angular part
var config = {
transformResponse: function (data, headers) {
if(headers("content-type") === "application/json" && angular.isString(data)) {
try {
data = JSON.parse(data);
} catch (e) {
// if parsing error, try another parser
// or just fix commas, if you know for sure that the problem is in commas
data = JSON2.parse(data);
}
return data;
} else {
return data;
}
}
};
$http.get("rules.json", config).success(function (data) {
$scope.rules = data;
});
So as you said, the JSON is wrongly generated on the server you are taking it from, can you change the way it is generated there? (Follow this: Can you use a trailing comma in a JSON object?)
In case you are unable to do so, you need to use something like mentioned here:
Can json.loads ignore trailing commas?
library to repair a JSON object, like: https://www.npmjs.com/package/jsonrepair
(try some online fix tool here: http://www.javascriptformat.com/)
or some regexp magic