The json file displays the wrong format - javascript

I'm using ajax to write json files. But the file display format is not correct.
AJAX:
$.ajax
({
type: "GET",
dataType : 'json',
contentType: "application/json",
async: false,
url: 'save_json.php',
data: {
data: JSON.stringify(data)
},
success: function () {alert("Thanks!"); },
failure: function() {alert("Error!");}
});
SAVE_JSON.PHP:
<?php
$myFile = "profile.json";
$fh = fopen($myFile, 'w') or die("can't open file");
$stringData = $_GET["data"];
fwrite($fh, $stringData);
fclose($fh)
?>
It shows the following:
{"profile":[{"no":1,"firstName":"C","lastName":"D","age":25,"sex":"M","country":"US","phoneNumber":"019878736729","email":"johnsmith#example.com"},{"no":2,"firstName":"A","lastName":"B","age":28,"sex":"M","country":"VN","phoneNumber":"84928374839","email":"nguyentam#example.com"}]}
But i want to display with correct format as follows:
{
"profile": [
{
"no": 1,
"firstName": "C",
"lastName": "D",
"age": 25,
"sex": "M",
"country": "US",
"phoneNumber": "019878736729",
"email": "johnsmith#example.com"
},
{
"no": 2,
"firstName": "A",
"lastName": "B",
"age": 28,
"sex": "M",
"country": "VN",
"phoneNumber": "84928374839",
"email": "nguyentam#example.com"
}
]
}
Can somebody help me?

Let's be clear about the two parts in this and what each part is doing.
Your JavaScript file is taking an object ("data") and turning it into a JSON string with the call to JSON.stringify(). It is then sending it to your PHP server.
Your PHP server is saving a string to the file. It isn't handling this string as a JSON string at all - it doesn't care.
You have a bunch of approaches how you can handle this. You can, for example, turn the string back into an object on the PHP side and dump out the formatted version:
$obj = json_decode($string_data,true);
$formatted_json = json_encode($obj, JSON_PRETTY_PRINT);
fwrite($fh, $formatted_json);
You could also do this formatting on the JavaScript side, replacing your call to JSON.stringify() with one with additional parameters:
JSON.stringify(data,null,4)
The null indicates that you're not going to use a replacer function, while the 4 is how many spaces to indent the pretty printing.
Which method you use is up to you and how much bandwidth you want to use (sending the formatted version takes up more space).
Keep in mind, however, that JSON parsers don't use this extra space - it is all formatting to help you (or some other human) read it.
(And #Quentin raises an excellent point in the comments to your question - using "GET" is a bad idea in this case for a lot of reasons. Switch to "PUT" or, at worst, "POST".)

Related

Outputting JSON from Curl APi call to Ajax

I am working on a course project in which I am required to use php to make api calls.
The Ajax call looks like this:
$('#btnOneRun').click(function() {
$.ajax({
url: "libs/php/getCapitalSummary.php",
type: 'POST',
dataType: 'json',
success: function(result) {
if (result.status.name == "ok") {
console.log(result)
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(errorThrown)
}
});
});
The php api call looks like this:
<?php
// remove for production
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$executionStartTime = microtime(true);
$url='http://api.geonames.org/wikipediaSearchJSON?formatted=true&q=london&maxRows=1&username=flightltd&style=full';
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$url);
$result=curl_exec($ch);
curl_close($ch);
$decode = json_decode($result, true);
$output['status']['code'] = "200";
$output['status']['name'] = "ok";
$output['status']['description'] = "success";
$output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms";
$output['data'] = $decode['geonames'];
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($output);
?>
This works perfectly. I have used the same routine to make similar calls go the geonames API and had no issues doing so as they provide the name of the root object returned. In the example above, it is called geonames
$output['data'] = $decode['geonames'];
I am trying to use this pattern to make a call to the accuweather API. For this however, I don't have the name of the root object.
I used the routine above, changing that specific line of code to $output['data'] = $result; and voila, I can see where geonames is coming from.
{
"status": {
"code": "200",
"name": "ok",
"description": "success",
"returnedIn": "120 ms"
},
"data": "{\"geonames\": [{\n \"summary\": \"London is the capital and most populous city of England and the United Kingdom. Standing on the River Thames, London has been a major settlement for two millennia, its history going back to its founding by the Romans, who named it Londinium (...)\",\n \"elevation\": 8,\n \"geoNameId\": 2643743,\n \"feature\": \"city\",\n \"lng\": -0.11832,\n \"countryCode\": \"GB\",\n \"rank\": 100,\n \"thumbnailImg\": \"http://www.geonames.org/img/wikipedia/43000/thumb-42715-100.jpg\",\n \"lang\": \"en\",\n \"title\": \"London\",\n \"lat\": 51.50939,\n \"wikipediaUrl\": \"en.wikipedia.org/wiki/London\"\n}]}"
}
At this point I thought: "Now I just need to do the same with the API call to Accuweather and I will be able to find what I need to type between the curly brackets on $output['data'] = $decode['what_goes_here?']; but when I tried that, the JSON return does not display an object like the one above.
The JSON returned from the accuweather API when called straight from my javascript file, or through the example in their website, looks like this:
[
{
"LocalObservationDateTime": "2022-03-10T06:47:00+00:00",
"EpochTime": 1646894820,
"WeatherText": "Light rain",
"WeatherIcon": 12,
"HasPrecipitation": true,
"PrecipitationType": "Rain",
"IsDayTime": true,
"Temperature": {
"Metric": {
"Value": 8,
"Unit": "C",
"UnitType": 17
},
"Imperial": {
"Value": 46,
"Unit": "F",
"UnitType": 18
}
},
"MobileLink": "http://www.accuweather.com/en/gb/london/ec4a-2/current-weather/328328?lang=en-us",
"Link": "http://www.accuweather.com/en/gb/london/ec4a-2/current-weather/328328?lang=en-us"
}
]
I am asking for help with one of two things:
a) A way to decode that JSON object without knowing what that object name is and output that to the AJAX call, or;
b) Receive the decoded object on javascript and decode it to access its properties there.
I immensely thank you in advance.
Edit: I looked more into PHP and realized that I did not understand that the php routine was simply using bracket notation to access the properties of the decoded object: $decode['geonames'].
I carried on looking into it and realized that I could use JSON.parse() in my javascript file.
So I changed that specific line of code in the php file to $output['data'] = $result;
Then on my ajax call I can access the properties of the JSON returned after using calling JSON.parse(result.data) as shown below:
$('#btnOneRun').click(function() {
$.ajax({
url: "libs/php/getWeather.php",
type: 'POST',
dataType: 'json',
success: function(result) {
if (result.status.name == "ok") {
console.log(JSON.parse(result.data))
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(errorThrown)
}
});
});
This is logged as:
[
{
"LocalObservationDateTime": "2022-03-10T08:13:00+00:00",
"EpochTime": 1646899980,
"WeatherText": "Mostly cloudy",
"WeatherIcon": 6,
"HasPrecipitation": false,
"PrecipitationType": null,
"IsDayTime": true,
"Temperature": {
"Metric": {
"Value": 9.1,
"Unit": "C",
"UnitType": 17
},
"Imperial": {
"Value": 48,
"Unit": "F",
"UnitType": 18
}
},
"MobileLink": "http://www.accuweather.com/en/gb/london/ec4a-2/current-weather/328328?lang=en-us",
"Link": "http://www.accuweather.com/en/gb/london/ec4a-2/current-weather/328328?lang=en-us"
}
]

Date json Object json in angularjs

I have json result which contain set of json objects.I could not get json object because json object is in integer value.Here is my json result
[{
"serverdatetime": "2016-09-23 12:21:31",
"game_result_array": {
"2016-09-23": [{
"eShowOnHome": "Yes",
"dModifiedDate": "2016-09-22",
"eText": "No",
"eTodayGame": "No",
"eDelay": "No",
"eInvert": "None",
"eResultOrder": "No",
"iHGameID": "56444",
"iGameID": "120",
"vGameTitle": "Gana M\u00e1s",
"eStats": "Yes",
"vUrl": "gana-mas-loteria-nacional",
"vGameLogo": "https:\/\/s3.amazonaws.com\/cdn.kiskooloterias.com\/dominicanas\/upload\/game_logo\/120\/loteria-nacional-dominicana.jpg",
"companymodifieddate": "2011-12-19 13:35:54",
"vCompanyLogo": "https:\/\/s3.amazonaws.com\/cdn.kiskooloterias.com\/dominicanas\/upload\/company\/76\/1373805675_loteria-nacional.jpg",
"gamemodifieddate": "2016-01-05",
"iCompanyID": "76",
"vCompanyName": "Loter\u00eda Nacional",
"vCompanyurl": "loteria-nacional-resultados",
"dLastLotteryDate": "2016-09-22",
"tScore": "28 01 96"
}]
},
"company_ids": "75,76,77,78,84",
"game_ids": "93,94,95,96,98,127,92,111,120,131,100,101,102,114,117,108,171,172",
"success": "1",
"message": "Record found"
}]
Here is the code what i tried
$http({
url : baseUrl,
method :'Post',
data : param
})
.success(function (result) {
$scope.rank =result.game_result_array["2016-09-23"].eShowOnHome;
}
Is there anyway to get json objects? help me. Thanks in advance
game_result_array is an array, so you need to specify the index.
This should work fine.
$scope.rank =result.game_result_array["2016-09-23"][0].eShowOnHome;
You could cast variable that are meant to be integer, Because When Calling From The endpoint, the json with integer types will be shown as strings.
example below shows how you do that using laravel/lumen
$x = Data::all();
return (int)$x->price;
hope you get the idea

Return JSON results as JS array with AJAX?

Apologies in advance - I am new to this and so other answers have not been able to help me.
I have used AJAX to send data to a PHP script (part of a 3rd party API). The PHP script returns the results as JSON, but I have no idea how to format these on my HTML page.
Ultimately, I would like to save the JSON results as an array and then use JS/Jquery to format them on the page.
I am not sure how to modify the PHP and AJAX scripts to achieve this. Can anyone point me in the right direction?
My AJAX:
$.ajax({
type: 'POST',
url: 'calculator.php',
data: {toPostcode: toPostcodeValue, parcelLengthInCMs: parcelLengthInCMsValue, parcelHeighthInCMs: parcelHeighthInCMsValue, parcelWidthInCMs: parcelWidthInCMsValue, parcelWeightInKGs: parcelWeightInKGsValue},
success: function(data) {
<!--NOT SURE WHAT TO PUT HERE-->
}
})
PHP (after the calculator does its thing - not sure if it needs to be changed):
$serviceTypesJSON = json_decode($rawBody);
echo json_encode($serviceTypesJSON);
The expected JSON results should look like:
{
"services": {
"service" : [
{
"code": "AUS_PARCEL_REGULAR",
"name": "Parcel Post (your own packaging)",
"speed": 2,
"price": 6.95,
"max_extra_cover": 5000,
"extra_cover_rule": "100,1.5,1.5",
"icon_url": "http://test-static.npe.auspost.com.au/api/images/pac/regular_post_box.png",
"description": "Based on the size and weight you've entered",
"details": "Check our ",
"delivery_time": "Delivered in up to 3 business days",
"ui_display_order": 1,
"options": {
"option": [
{
"code": "AUS_SERVICE_OPTION_STANDARD",
"name": "Standard Service",
"price": "0.00",
"price_type": "static",
"option_type": "optional",
"ui_display_order": 1
},
{
"code": "AUS_SERVICE_OPTION_SIGNATURE_ON_DELIVERY",
"name": "Signature on Delivery",
"price": 2.95,
"price_type": "static",
"option_type": "optional",
"tooltip": "Signature on Delivery provides you with the peace of mind that your item has been delivered and signed for.",
"ui_display_order": 2,
"suboptions": {
"option": {
"code": "AUS_SERVICE_OPTION_EXTRA_COVER",
"name": "Extra Cover",
"option_type": "optional",
"price_type": "dynamic",
"tooltip": "Extra Cover provides cover for loss, damage or theft of your item and will fully compensate you to the value specified for your item.",
"ui_display_order": 1
}
}
}
]
}
},
You can do two things, if the return data is JSON use dataType: "json" in the AJAX call.
Edit 1
If you are using dataType: "json". Which is more preferred if you are sure the data return is JSON string. data variable in the success will directly give you the JSON object. I think you can access it like data['services'].
success: function (data) {
jsonObj = $.parseJSON(data);
//this gives you the inner onject of the return data
servicesObj = jsonObj.services;
}
Or you can just get the data then use jQuery.parseJSON() to parse the data string into JSON object.
$.ajax({
type: 'POST',
url: 'calculator.php',
data: {
toPostcode: toPostcodeValue,
parcelLengthInCMs: parcelLengthInCMsValue,
parcelHeighthInCMs: parcelHeighthInCMsValue,
parcelWidthInCMs: parcelWidthInCMsValue,
parcelWeightInKGs: parcelWeightInKGsValue
},
success: function (data) {
jsonObj = $.parseJSON(data);
//this gives you the inner onject of the return data
servicesObj = jsonObj.services; //or jsonObj["services"]
}
})
Your success function will never be called if you are using
echo json_encode(); in your php script.
You should add dataType:'json' after type:'POST' and then your success function will get called and will get the result returned by server in data

display json data using xhrget (DOJO)

I am unable to figure out what is the problem with displaying json data..below is the code
var xhrGet1 = dojo.xhrGet({
url: "Page/",
handleAs: "json",
handle: function(response)
{
dojo.byId('json-data').innerHTML = response.questions[0];
}
});
Html
<div id='json-data'></div>
And my json file looks like this
{
"Info": {
"PURPOSE": ".... ",
},
"questions": [
{
"ID": 1,
"Question": "User ID",
"Information": "",
}, {
"ID": 2,
"Question": "Name",
"Information": "",
}
],
so on...any ideas??
The property handleAs : "json" in your xhr call makes the incoming json automatically eval'ed to javascript objects. So, you have to convert your javascript object back to string using JSON.stringify.
e.g. :
dojo.byId('json-data').innerHTML = JSON.stringify(response.questions[0]);
You can also use dojo.toJson for the same purpose. It uses json.stringify but has the benefit of having a second argument ("prettyprint"), allowing you to pretty-print out of the box, like this :
dojo.byId('json-data').innerHTML = dojo.toJson(response.questions[0], true);
wrap your JSON with PRE and CODE tags.
So:
dojo.byId('json-data').innerHTML = "<pre>code>" + response.questions[0] + "</code></pre>";
Also see: Display JSON as HTML for some libraries that can help you pretty-format your JSON when rendering in the browser

Using updateFromJS is replacing values when it should be adding them

I have this code:
var attachmentsModel = {
convAttachments: ko.mapping.fromJS([])
};
$(function() {
ko.applyBindings(attachmentsModel)
refreshConvAttachments();
});
function refreshConvAttachments() {
$.ajax({
url: '/xxxxxxx/',
success: function (dataJS) {
// Send KO the data
ko.mapping.updateFromJS(attachmentsModel.convAttachments, dataJS);
}
});
}
The AJAX call above returns:
[{
"title": "BillGates",
"added_by": "xxx",
"thumb": "urlhere",
"id": 410,
"link": "/link/410",
"added_on": "2011-02-22T12:57:09-08:00"
}, {
"title": "biz-stone",
"added_by": "xxx",
"urlhere",
"id": 411,
"link": "/link/411",
"added_on": "2011-02-22T12:57:53-08:00"
}]
This works fine. Later though the user is able to add an attachment, and that's where it's breaking. While it adds the new attachment to the mode, and displays on the page, it removes all the previously loaded items in the attachmentsModel.convAttachments.
Later on, this happens:
ko.mapping.updateFromJS(attachmentsModel.convAttachments, file);
Ajax Returns:
[{
"title": "eric_schmidt",
"added_by": "xxx",
"thumb": "xxxxxx",
"id": 417,
"link": "/link/417",
"added_on": "2011-02-22T13:16:45-08:00"
}]
I hope that gives a clear walk through, if not please let me know. Any ideas why knockoutjs is kill everything when I use updateFromJS?
ko.mapping.updateFromJS() expects that you are receiving the complete list of items that was originally prepared with ko.mapping.fromJS(). Any items that are missing from the original are considered to be deleted and any new items in the updates are considered additions. So, currently the mapping plugin will not allow you to do incremental updates in this way.
If you are doing incremental updates, your best bet would be to locate the items that you need to update and either replace them completely or replace individual observables on each item.
you could always try using
$.extend(attachmentsModel.convAttachments,ko.mapping.fromJS(dataJS));
Although i am not quite sure if that will update all the bindings properly, you might have to reply the binding by calling
ko.applyBindings(attachmentsModel)

Categories