I've been trying to format a URL POST with objects in my array as they're required to post to my REST API. I'm forced to use an archaic API POST system from a vendor and have been trying to hack together a solution.
Basically the JSON looks similar to:
{"api_key": "12234",
"server_id:"qwp2222",
"recipients": [
{"email":"john#doe.com",
"name": "john doe"}]
}
I am trying to format the Array'd key-value pairs as part of the URL so it would post to the endpoint without much fanfare.
I have the rest of the URL together without issue, it is just the recipients' array that is the problem.
How should I write the POST URL in order to make sure that I can post the array of objects correctly?
I appreciate all the help in advance!
Does not work here, but this code will make linear structure from your JSON, create form from and submit to itself.
If you run it on local or anywhere else and add f.action = 'your get or post page', it will send data properly.
var data = {
api_key: '12234',
server_id: 'qwp2222',
recipients: [{
email: 'john#doe.com',
name: 'john doe'
}]
};
function collectItems(res, json) {
for (var a in json) {
if (json[a].constructor === Array ||
json[a].constructor === Object) {
collectItems(res, json[a]);
} else {
res.push([a, json[a]]);
}
}
}
var all = [];
collectItems(all, data);
var f = document.createElement('FORM');
f.method = 'post';
// default get: ...?api_key=12234&server_id=qwp2222&email=john#doe.com&name=john+doe
for (var e in all) {
var i = document.createElement('INPUT');
i.name = all[e][0];
i.value = all[e][1];
i.type = 'hidden'; // do not show values sent
f.appendChild(i);
}
if (location.search) {
alert("Submit result:" & location.href);
} else {
document.body.appendChild(f);
f.submit();
}
Related
My using package http
I have this method in my app to send post request with files. In my case I send files and also fields with dynamic values. I tried send List<String> but server (backend) return me error with message:
The seedlings field must be an array.
Example seedlings list value:
List<String> seedlings = ['Apple', 'Banana'];
Code:
Future post(String path, data) async {
await _getToken();
var url = '${ApiConstants.BASE_URL}$path';
var uri = Uri.parse(url);
var request = MultipartRequest('POST', uri);
data.forEach((key, item) async {
if (item == null) return null;
if (item is File) {
request.files.add(await MultipartFile.fromPath(
'file',
item.path,
));
} else {
request.fields[key] = item is num
? item.toString()
: item is List
? item.toString()
: item;
}
});
request.headers['Content-type'] = 'application/json';
request.headers['Accept'] = 'application/json';
var response = await request.send();
}
In my case all fields sent to server except fields with list of values like array
This might be old, but you can easily do this by adding the array items into a form data array
final FormData formData = FormData({});
// Add all normal string request body data
formData.fields.add(MapEntry("name", "Olayemii"));
formData.fields.add(MapEntry("age", 99));
// Add all files request body data
formData.files.add(MapEntry("profile_photo", file));
// Add the array item
List<String> seedlings = ['Apple', 'Banana'];
seedlings.forEach((element) {
formData.fields.add(MapEntry("seedlings[]", element.toString()));
});
I have found an answer for this which I have posted in another similar question. I'll just put the code snippet here.
final request = http.MultipartRequest('Post', uri);
List<String> ManageTagModel = ['xx', 'yy', 'zz'];
for (String item in ManageTagModel) {
request.files.add(http.MultipartFile.fromString('manage_tag_model', item));
}
Basically you have to add the list as files with fromString() method.
Find the original answer here-
https://stackoverflow.com/a/66318541/7337717
I am working with Flutter and am currently trying to create a graph. I am looking to parse this JSON Array from the link below. My issue is that the information provided in the "prices" object, the values are all inside arrays themselves. I want to get those values and split them into an X and Y list but I have no idea how to accomplish this. I posted a snippet of the JSON data below.
https://api.coingecko.com/api/v3/coins/bitcoin/market_chartvs_currency=usd&days=1
I am only familiar with parsing data by creating a class and constructor. Then create a fromJSON(Map<String, dynamic> json) class and putting the data into a list, as shown in the code snippet below that I created from another URL with object values. How could I go about parsing this array JSON data into two list data?
CODE TO PARSE JSON
List<Coins> _coins = List<Coins>();
Future<List<Coins>> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);
var coins = List<Coins>();
if (response.statusCode == 200) {
var coinsJSON = json.decode(response.body);
for (var coinJSON in coinsJSON) {
coins.add(Coins.fromJson(coinJSON));
}
}
return coins;
}
#override
void initState() {
fetchCoins().then((value) {
setState(() {
_coins.addAll(value);
});
});
super.initState();
}
class Coins{
String symbol;
String name;
Coins(this.symbol, this.name);
Coins.fromJson(Map<String, dynamic> json) {
symbol = json['symbol'];
name = json['name'];
JSON DATA SNIPPET
{
"prices":[
[
1566344769277,
10758.856131083012
],
[
1566345110646,
10747.91694691537
],
[
1566345345922,
10743.789313302059
],
]
}
EDIT: SOLVED WITH THE HELP OF #EJABU.
class HistoricalData {
List prices;
List<num> listX = [];
List<num> listY = [];
HistoricalData(this.prices,this.listX, this.listY);
HistoricalData.fromJson(Map<String, dynamic> json) {
prices = json['prices'];
for (var price in prices) {
listX.add(price[0]);
listY.add(price[1]);
}
}
You may try this...
New class Coins definition:
class Coins {
List<num> listX = [];
List<num> listY = [];
Coins(this.listX, this.listY);
Coins.fromJson(Map<String, dynamic> json) {
List<List<num>> prices = json['prices'];
for (var price in prices) {
listX.add(price[0]);
listY.add(price[1]);
}
}
}
Then later you can fetch it by these lines :
// Future<List<Coins>> fetchCoins() async { // Remove This
Future<Coins> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);
// var coins = List<Coins>(); // Remove This
Coins coins;
if (response.statusCode == 200) {
var coinsJSON = json.decode(response.body);
// Remove This
// for (var coinJSON in coinsJSON) {
// coins.add(Coins.fromJson(coinJSON));
// }
//
coins = Coins.fromJSON(coinsJSON);
}
return coins;
}
Accessing Data in Widget
In Widgets , our expected variable resides as property inside Coins class.
For example, if you use FutureBuilder, you may use these lines:
child: FutureBuilder(
future: fetchCoins(),
builder: (_, __) {
return SomeChartWidget(
listX: coins.listX,
listY: coins.listY,
);
},
),
Generating Serializers automatically
I suggest you take a look at https://pub.dev/packages/json_serializable, which is a package that does the boilerplate code generation for you. Although it might me a bit overkill to add something like this to your code or your workflow, automatically generating serializers is very convenient.
Not that in order to have custom sub-classes, they need to provide serialization as well.
If you want to extend your knowledge even further, you can also have a look at https://pub.dev/packages/built_value and https://pub.dev/packages/built_value_generator
Iam currently using flask and google datastore and working on it
#app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
pass
return jsonify({'result': True})
Ive used get and post and also put method for inserting retrieving and updating now i need to delete using delete request
I tried to pass the respective id value by using href in my html page but I found it doesnt work that way !
def delete_method(task_id):
k = ndb.Key('ToDo', task_id)
k.delete()
return jsonify({"success":True})
The above code works fine and the ajax request is as follows
function delData(){
var id = this.id
//console.log(id)
var url = '/DELETE/todo/api/v1.0/task/';
var xhr = new XMLHttpRequest();
xhr.open("DELETE", url+id, true);
xhr.onload = function () {
var jsonResponse = JSON.parse(xhr.responseText);
if (xhr.readyState == 4 && xhr.status == "200") {
console.log(jsonResponse);
var elem = document.getElementById(id).parentNode;
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}
else {
console.error(jsonResponse);
}
}
xhr.send(null);
}
I am successfully calling $http.get in my Angular controller and getting back a large json object. Like this:
var self=this;
self.createNewStatusReport = function()
{
$http.get(self.NewStatusReportUrl).then(function(response)
{
self.AngularModel.StatusReportJsons.push(response.data);
});
};
The returned json includes many dates. The format, unfortunately, looks like this: /Date(1420099200000)/. Here's a simplified piece of the response data:
{
"StatusReportID": 25,
"DueDate": "/Date(1468566000000)/",
"SubmitDate": null,
"WorkStatement": [
{
"WorkStatementID": 41,
"Milestone": [
{
"MilestoneID": 501,
"ContractorComments": null,
"Title": "Do some specific piece of work",
"StartDate": "/Date(1459494000000)/",
"EndDate": "/Date(1469948400000)/",
"IsCompleted": false,
...
I also have (some) control over the server side, but can't change the date types in StatusReportJson from DateTime? to string. It is MVC written in C#:
[HttpGet]
public JsonResult NewStatusReport(string agreementNumber)
{
var statusReport = StatusReports.GetStatusReport(25);
return Json(new StatusReportJson(statusReport), JsonRequestBehavior.AllowGet);
}
Is there an easy way to recursively convert these date strings to date objects? The response data comes to me already parsed; can I insert my own parse step? On the server side, can I make the dates come in as date strings that look more like "2016-04-01T00:00:00" or simply "2016-04-01" without modifying my StatusReportJson object's data types? Others have already solved the conversion problem here: How do I format a Microsoft JSON date? I need help structuring where to put the solution so it is effective in my case. Thanks for helping!
Hope this solves your problem:
$scope.DateIssue = function(input) {
input = '/Date(1468566000000)/';
$scope.formatedDate = input.toString().replace('/Date(', '').replace(')/', '');
$scope.formatedDate = $filter('date', $scope.formatedDate);
return $scope.formatedDate
};
Here's how I solved this. First, I used the JavaScript serializer on the server side like this:
[HttpGet]
public JsonResult NewStatusReport(string agreementNumber)
{
var statusReport = StatusReports.GetStatusReport(25);
var statusReportJson = new StatusReportJson(statusReport);
var json = new JavaScriptSerializer().Serialize(statusReportJson);
return Json(json, JsonRequestBehavior.AllowGet);
}
Then, on the client side, I pulled in code from this excellent page http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html and called it like this:
var self = this;
$http.get(self.NewStatusReportUrl).then(function(response)
{
var jsonObject = jQuery.parseJSON(response.data, true);
self.AngularModel.StatusReportJsons.push(jsonObject);
});
Thanks to Robert Koritnik for the answer! And thanks to everyone who helped!
A little late, but I thought helpful.
Most of the suggestions were to locally convert it. In my case the date is returned as string (with Timezone info).
E.g. '2018-06-01T13:57:41.3867449Z'
So I created a common service for getJson & PostJson and in handled responses there with '$q'.
if (response.data) {
// Check for datetime object & convert
// TODO:: *** May impact performance, so check later or use momentJS
//console.info('Before-convertDateStringsToDates:', new Date());
appUtils.convertDateStringsToDates(response.data);
//console.info('After-convertDateStringsToDates:', new Date());
}
My appUtil method is as below:
// --------------------------------------------------------------------------------
// Ref: http://aboutcode.net/2013/07/27/json-date-parsing-angularjs.html
// Function to convert string (as ReGex format) property to date - used as generic in Common Serivce.
convertDateStringsToDates(input) {
// ReGex for format we receive from Web API e.g. "1980-05-09T00:00:00Z"
var jsonDateTimeFormatRegex = "((?:2|1)\\d{3}(?:-|\\/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|\\/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|\\s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))";
// Ignore things that aren't objects.
if (typeof input !== "object") return input;
for (var key in input) {
if (!input.hasOwnProperty(key)) continue;
var value = input[key];
var match;
// Check for string properties which look like dates.
// TODO: Improve this regex to better match ISO 8601 date strings.
if (typeof value === "string" && (match = value.match(jsonDateTimeFormatRegex))) {
// Assume that Date.parse can parse ISO 8601 strings, or has been shimmed in older browsers to do so.
//console.info(match[0]);
var date = new Date(match[0]); // Need to convert to UTC. Ref: https://stackoverflow.com/a/14006555/1161069
input[key] = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
// var milliseconds = Date.parse(match[0]);
// if (!isNaN(milliseconds)) {
// input[key] = new Date(milliseconds);
// }
} else if (typeof value === "object") {
// Recurse into object
this.convertDateStringsToDates(value);
}
}
}
Now, after each GET or POST request, I get my JSON with proper dates.
Just in case someone wants to know Web API code, it's as below:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
//var cors = new System.Web.Http.Cors.EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
// other code ......
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
//jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
JsonSerializerSettings jSettings = new JsonSerializerSettings()
{
Formatting = Formatting.None
};
jSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
jsonFormatter.SerializerSettings = jSettings;
// rest of the code....
}
I try to iterate throug an array of ids and make a ajax request for each id. subsequentely each response object is pushed in an array/ so far no problem, however, the problem starts when i try to access the responses in the array. the strange thing is that in the console log the responses are shown (ouside the array though, see below) but the properties of the array objects are empty/ it seems i generated an empty object with some data attached to it/ my question is how can i access the objects that are in (or not in?) the array
var getAssoc = {
returnProds: function (idCache) {
var id = idCache;
var prodData = [];
var counter = id.length;
$.each(id, function (i) {
$.ajax({
url: "myurl.php?",
data: {
'id': id[i]
},
success: function (data) {
prodData[i] = data;
counter--;
if (counter === 0) console.log(prodData);
},
})
});
}
};
console log looks like this. testing for number of properties returns 0
[]
0 Object { array={...}}
1 Object { array={...}}
2 Object { array={...}}
3 Object { array={...}}
In you success callback Try parsing the response coming from your server:
jQuery.parseJSON(data);