I'm trying to load a local JSON file but it won't work. Here is my JavaScript code (using jQuery):
var json = $.getJSON("test.json");
var data = eval("(" +json.responseText + ")");
document.write(data["a"]);
The test.json file:
{"a" : "b", "c" : "d"}
Nothing is displayed and Firebug tells me that data is undefined. In Firebug I can see json.responseText and it is good and valid, but it's strange when I copy the line:
var data = eval("(" +json.responseText + ")");
in Firebug's console, it works and I can access data.
Does anyone have a solution?
$.getJSON is asynchronous so you should do:
$.getJSON("test.json", function(json) {
console.log(json); // this will show the info it in firebug console
});
I had the same need (to test my angularjs app), and the only way I found is to use require.js:
var json = require('./data.json'); //(with path)
note: the file is loaded once, further calls will use the cache.
More on reading files with nodejs: http://docs.nodejitsu.com/articles/file-system/how-to-read-files-in-nodejs
require.js: http://requirejs.org/
In a more modern way, you can now use the Fetch API:
fetch("test.json")
.then(response => response.json())
.then(json => console.log(json));
All modern browsers support Fetch API. (Internet Explorer doesn't, but Edge does!)
or with async/await
async function printJSON() {
const response = await fetch("test.json");
const json = await response.json();
console.log(json);
}
source:
Using Fetch
Fetch in Action
Can I use...?
How to Use Fetch with async/await
If you want to let the user select the local json file (anywhere on the filesystem), then the following solution works.
It uses FileReader and JSON.parser (and no jquery).
<html>
<body>
<form id="jsonFile" name="jsonFile" enctype="multipart/form-data" method="post">
<fieldset>
<h2>Json File</h2>
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
</fieldset>
</form>
<script type="text/javascript">
function loadFile() {
var input, file, fr;
if (typeof window.FileReader !== 'function') {
alert("The file API isn't supported on this browser yet.");
return;
}
input = document.getElementById('fileinput');
if (!input) {
alert("Um, couldn't find the fileinput element.");
}
else if (!input.files) {
alert("This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
alert("Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = receivedText;
fr.readAsText(file);
}
function receivedText(e) {
let lines = e.target.result;
var newArr = JSON.parse(lines);
}
}
</script>
</body>
</html>
Here is a good intro on FileReader: http://www.html5rocks.com/en/tutorials/file/dndfiles/
If you're looking for something quick and dirty just load the data in the head of your HTML document.
data.js
var DATA = {"a" : "b", "c" : "d"};
index.html
<html>
<head>
<script src="data.js" ></script>
<script src="main.js" ></script>
</head>
...
</html>
main.js
(function(){
console.log(DATA); // {"a" : "b", "c" : "d"}
})();
I should mention that your heap size (in Chrome) is about 4GBs, so if your data is larger than that you should find another method. If you want to check another browser try this:
window.performance.memory.jsHeapSizeLimit / 1024 / 1024 / 1024 + " GBs"
// "4.046875 GBs"
Update ES6:
Instead of using the <script> tag to load your data you can load it directly inside you're main.js using the import assert
import data from './data.json' assert {type: 'json'};
how to using XMLHttpRequest to load the local json file
ES5 version
// required use of an anonymous callback,
// as .open() will NOT return a value but simply returns undefined in asynchronous mode!
function loadJSON(callback) {
var xObj = new XMLHttpRequest();
xObj.overrideMimeType("application/json");
xObj.open('GET', './data.json', true);
// 1. replace './data.json' with the local path of your file
xObj.onreadystatechange = function() {
if (xObj.readyState === 4 && xObj.status === 200) {
// 2. call your callback function
callback(xObj.responseText);
}
};
xObj.send(null);
}
function init() {
loadJSON(function(response) {
// 3. parse JSON string into JSON Object
console.log('response =', response);
var json = JSON.parse(response);
console.log('your local JSON =', JSON.stringify(json, null, 4));
// 4. render to your page
const app = document.querySelector('#app');
app.innerHTML = '<pre>' + JSON.stringify(json, null, 4) + '</pre>';
});
}
init();
<section id="app">
loading...
</section>
ES6 version
// required use of an anonymous callback,
// as .open() will NOT return a value but simply returns undefined in asynchronous mode!
const loadJSON = (callback) => {
const xObj = new XMLHttpRequest();
xObj.overrideMimeType("application/json");
// 1. replace './data.json' with the local path of your file
xObj.open('GET', './data.json', true);
xObj.onreadystatechange = () => {
if (xObj.readyState === 4 && xObj.status === 200) {
// 2. call your callback function
callback(xObj.responseText);
}
};
xObj.send(null);
}
const init = () => {
loadJSON((response) => {
// 3. parse JSON string into JSON Object
console.log('response =', response);
const json = JSON.parse(response);
console.log('your local JSON =', JSON.stringify(json, null, 4));
// 4. render to your page
const app = document.querySelector('#app');
app.innerHTML = `<pre>${JSON.stringify(json, null, 4)}</pre>`;
});
}
init();
<section id="app">
loading...
</section>
online demo
https://cdn.xgqfrms.xyz/ajax/XMLHttpRequest/index.html
I can't believe how many times this question has been answered without understanding and/or addressing the problem with the Original Poster's actual code. That said, I'm a beginner myself (only 2 months of coding). My code does work perfectly, but feel free to suggest any changes to it. Here's the solution:
//include the 'async':false parameter or the object data won't get captured when loading
var json = $.getJSON({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false});
//The next line of code will filter out all the unwanted data from the object.
json = JSON.parse(json.responseText);
//You can now access the json variable's object data like this json.a and json.c
document.write(json.a);
console.log(json);
Here's a shorter way of writing the same code I provided above:
var json = JSON.parse($.getJSON({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}).responseText);
You can also use $.ajax instead of $.getJSON to write the code exactly the same way:
var json = JSON.parse($.ajax({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}).responseText);
Finally, the last way to do this is to wrap $.ajax in a function. I can't take credit for this one, but I did modify it a bit. I tested it and it works and produces the same results as my code above. I found this solution here --> load json into variable
var json = function () {
var jsonTemp = null;
$.ajax({
'async': false,
'url': "http://spoonertuner.com/projects/test/test.json",
'success': function (data) {
jsonTemp = data;
}
});
return jsonTemp;
}();
document.write(json.a);
console.log(json);
The test.json file you see in my code above is hosted on my server and contains the same json data object that he (the original poster) had posted.
{
"a" : "b",
"c" : "d"
}
Add to your JSON file from the beginning
var object1 = [
and at the end
]
Save it
Then load it with pure js as
<script type="text/javascript" src="1.json"></script>
And now you can use it as object1 - its already loaded!
Works perfectly in Chrome and without any additional libraries
I'm surprised import from es6 has not been mentioned (use with small files)
Ex: import test from './test.json'
webpack 2< uses the json-loader as default for .json files.
https://webpack.js.org/guides/migrating/#json-loader-is-not-required-anymore
For TypeScript:
import test from 'json-loader!./test.json';
TS2307 (TS) Cannot find module 'json-loader!./suburbs.json'
To get it working I had to declare the module first. I hope this will save a few hours for someone.
declare module "json-loader!*" {
let json: any;
export default json;
}
...
import test from 'json-loader!./test.json';
If I tried to omit loader from json-loader I got the following error from webpack:
BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix
when using loaders.
You need to specify 'json-loader' instead of 'json',
see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed
Recently D3js is able to handle local json file.
This is the issue
https://github.com/mbostock/d3/issues/673
This is the patch inorder for D3 to work with local json files.
https://github.com/mbostock/d3/pull/632
Found this thread when trying (unsuccessfully) to load a local json file. This solution worked for me...
function load_json(src) {
var head = document.getElementsByTagName('head')[0];
//use class, as we can't reference by id
var element = head.getElementsByClassName("json")[0];
try {
element.parentNode.removeChild(element);
} catch (e) {
//
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
script.className = "json";
script.async = false;
head.appendChild(script);
//call the postload function after a slight delay to allow the json to load
window.setTimeout(postloadfunction, 100)
}
... and is used like this...
load_json("test2.html.js")
...and this is the <head>...
<head>
<script type="text/javascript" src="test.html.js" class="json"></script>
</head>
What I did was editing the JSON file little bit.
myfile.json => myfile.js
In the JSON file, (make it a JS variable)
{name: "Whatever"} => var x = {name: "Whatever"}
At the end,
export default x;
Then,
import JsonObj from './myfile.js';
In TypeScript you can use import to load local JSON files. For example loading a font.json:
import * as fontJson from '../../public/fonts/font_name.json';
This requires a tsconfig flag --resolveJsonModule:
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true
}
}
For more information see the release notes of typescript: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html
In angular (or any other framework), you can load using http get
I use it something like this:
this.http.get(<path_to_your_json_file))
.success((data) => console.log(data));
Hope this helps.
An approach I like to use is to pad/wrap the json with an object literal, and then save the file with a .jsonp file extension. This method also leaves your original json file (test.json) unaltered, as you will be working with the new jsonp file (test.jsonp) instead. The name on the wrapper can be anything, but it does need to be the same name as the callback function you use to process the jsonp. I'll use your test.json posted as an example to show the jsonp wrapper addition for the 'test.jsonp' file.
json_callback({"a" : "b", "c" : "d"});
Next, create a reusable variable with global scope in your script to hold the returned JSON. This will make the returned JSON data available to all other functions in your script instead of just the callback function.
var myJSON;
Next comes a simple function to retrieve your json by script injection. Note that we can not use jQuery here to append the script to the document head, as IE does not support the jQuery .append method. The jQuery method commented out in the code below will work on other browsers that do support the .append method. It is included as a reference to show the difference.
function getLocalJSON(json_url){
var json_script = document.createElement('script');
json_script.type = 'text/javascript';
json_script.src = json_url;
json_script.id = 'json_script';
document.getElementsByTagName('head')[0].appendChild(json_script);
// $('head')[0].append(json_script); DOES NOT WORK in IE (.append method not supported)
}
Next is a short and simple callback function (with the same name as the jsonp wrapper) to get the json results data into the global variable.
function json_callback(response){
myJSON = response; // Clone response JSON to myJSON object
$('#json_script').remove(); // Remove json_script from the document
}
The json data can now be accessed by any functions of the script using dot notation. As an example:
console.log(myJSON.a); // Outputs 'b' to console
console.log(myJSON.c); // Outputs 'd' to console
This method may be a bit different from what you are used to seeing, but has many advantages. First, the same jsonp file can be loaded locally or from a server using the same functions. As a bonus, jsonp is already in a cross-domain friendly format and can also be easily used with REST type API's.
Granted, there are no error handling functions, but why would you need one? If you are unable to get the json data using this method, then you can pretty much bet you have some problems within the json itself, and I would check it on a good JSON validator.
You can put your json in a javascript file. This can be loaded locally (even in Chrome) using jQuery's getScript() function.
map-01.js file:
var json = '{"layers":6, "worldWidth":500, "worldHeight":400}'
main.js
$.getScript('map-01.js')
.done(function (script, textStatus) {
var map = JSON.parse(json); //json is declared in the js file
console.log("world width: " + map.worldWidth);
drawMap(map);
})
.fail(function (jqxhr, settings, exception) {
console.log("error loading map: " + exception);
});
output:
world width: 500
Notice that the json variable is declared and assigned in the js file.
$.ajax({
url: "Scripts/testingJSON.json",
//force to handle it as text
dataType: "text",
success: function (dataTest) {
//data downloaded so we call parseJSON function
//and pass downloaded data
var json = $.parseJSON(dataTest);
//now json variable contains data in json format
//let's display a few items
$.each(json, function (i, jsonObjectList) {
for (var index = 0; index < jsonObjectList.listValue_.length;index++) {
alert(jsonObjectList.listKey_[index][0] + " -- " + jsonObjectList.listValue_[index].description_);
}
});
}
});
If you are using a local array for JSON - as you showed in your example in the question (test.json) then you can is the parseJSON() method of JQuery ->
var obj = jQuery.parseJSON('{"name":"John"}');
alert( obj.name === "John" );
getJSON() is used for getting JSON from a remote site - it will not work locally (unless you are using a local HTTP Server)
How I was able to load the data from a json file in to a JavaScript variable using simple JavaScript:
let mydata;
fetch('datafile.json')
.then(response => response.json())
.then(jsonResponse => mydata = jsonResponse)
Posting here as I didn't find this kind of "solution" I was looking for.
Note: I am using a local server run via the usual "python -m http.server" command.
$.getJSON only worked for me in Chrome 105.0.5195.125 using await, which works a script type of module.
<script type="module">
const myObject = await $.getJSON('./myObject.json');
console.log('myObject: ' + myObject);
</script>
Without await, I see:
Uncaught TypeError: myObject is not iterable
when resolving myObject.
Without type="module" I see:
Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
I haven't found any solution using Google's Closure library. So just to complete the list for future vistors, here's how you load a JSON from local file with Closure library:
goog.net.XhrIo.send('../appData.json', function(evt) {
var xhr = evt.target;
var obj = xhr.getResponseJson(); //JSON parsed as Javascript object
console.log(obj);
});
json_str = String.raw`[{"name": "Jeeva"}, {"name": "Kumar"}]`;
obj = JSON.parse(json_str);
console.log(obj[0]["name"]);
I did this for my cordova app, like I created a new javascript file for the JSON and pasted the JSON data into String.raw then parse it with JSON.parse
function readTextFile(srcfile) {
try { //this is for IE
var fso = new ActiveXObject("Scripting.FileSystemObject");;
if (fso.FileExists(srcfile)) {
var fileReader = fso.OpenTextFile(srcfile, 1);
var line = fileReader.ReadLine();
var jsonOutput = JSON.parse(line);
}
} catch (e) {
}
}
readTextFile("C:\\Users\\someuser\\json.txt");
What I did was, first of all, from network tab, record the network traffic for the service, and from response body, copy and save the json object in a local file. Then call the function with the local file name, you should be able to see the json object in jsonOutout above.
What worked for me is the following:
Input:
http://ip_address//some_folder_name//render_output.html?relative/path/to/json/fie.json
Javascript Code:
<html>
<head>
<style>
pre {}
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
</style>
<script>
function output(inp) {
document.body.appendChild(document.createElement('pre')).innerHTML = inp;
}
function gethtmlcontents(){
path = window.location.search.substr(1)
var rawFile = new XMLHttpRequest();
var my_file = rawFile.open("GET", path, true) // Synchronous File Read
//alert('Starting to read text')
rawFile.onreadystatechange = function ()
{
//alert("I am here");
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
//alert(allText)
var json_format = JSON.stringify(JSON.parse(allText), null, 8)
//output(json_format)
output(syntaxHighlight(json_format));
}
}
}
rawFile.send(null);
}
function syntaxHighlight(json) {
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
gethtmlcontents();
</script>
</head>
<body>
</body>
</html>
simplest way: save json file as *.js and include to html template as script.
js file like this:
let fileJsonData = {
someField: someValue,
...
}
include like this:
...
<script src="./js/jsonData.js"></script>
...
After include you can call to fileJsonData in global scope.
If you have Python installed on your local machine (or you don't mind install one), here is a browser-independent workaround for local JSON file access problem that I use:
Transform the JSON file into a JavaScript by creating a function that returns the data as JavaScript object. Then you can load it with <script> tag and call the function to get the data you want.
Here comes the Python code
import json
def json2js(jsonfilepath, functionname='getData'):
"""function converting json file to javascript file: json_data -> json_data.js
:param jsonfilepath: path to json file
:param functionname: name of javascript function which will return the data
:return None
"""
# load json data
with open(jsonfilepath,'r') as jsonfile:
data = json.load(jsonfile)
# write transformed javascript file
with open(jsonfilepath+'.js', 'w') as jsfile:
jsfile.write('function '+functionname+'(){return ')
jsfile.write(json.dumps(data))
jsfile.write(';}')
if __name__ == '__main__':
from sys import argv
l = len(argv)
if l == 2:
json2js(argv[1])
elif l == 3:
json2js(argv[1], argv[2])
else:
raise ValueError('Usage: python pathTo/json2js.py jsonfilepath [jsfunctionname]')
I'm learning JS & keep running into the problem of how to put documentation together to do this or that. e.g. Greasemonkey is documented, but you have to know a lot of other context not even referred to to use the greasepot wiki very well.
I've been trying various combinations of the following, for example, and I can only ever get "undefined" from the GM_xmhttprequest function, though:
var url = "https://en.wikipedia.org/wiki/CURL?action=render";
var fetchContent = console.log( function getContent(url) {
if (url.length < 0) {
return 0 ;
}
GM_xmlhttpRequest({
method: "GET",
url: url,
headers: {
"User-Agent": "Mozilla/5.0", // If not specified, navigator.userAgent will be used.
//"Accept": "text/xml" // If not specified, browser defaults will be used.
},
onload: function(response) {
//var responseXML = null;
alert(response.responseText);
// Inject responseXML into existing Object (only appropriate for XML content).
/*
if (!response.responseXML) {
responseXML = new DOMParser()
.parseFromString(response.responseText, "text/xml");
}
GM_log([
response.status,
response.statusText,
response.readyState,
response.responseHeaders,
response.responseText,
response.finalUrl,
responseXML
].join("\n"));
*/
}
});
} )
Yet I'm not sure I'm using it correctly:
Need to define something in 'onload'??
Need to create a var prior? (e.g. var responseHoldingObject = new Object(); ?) ?
etc.
And any advice to get the page-fetching I'm looking for going is appreciated. Goal is to fetch content and ultimately append it within another page (e.g. such as within textarea or div).
Learning JS with GreaseMonkey might be a bit advanced.
fetchContent will be assigned the return value of console.log, which is undefined because console.log does not return a value. And what you're logging is the function getContent itself. getContent is never evaluated.
Finally, you can never get a response from an asynchronous function to use outside of the callback reliably (except with polling). Basically it should be something like this (untested):
GM_xmlhttpRequest({
method: "GET",
url: url,
headers: {
"User-Agent": "Mozilla/5.0", // If not specified, navigator.userAgent will be used.
//"Accept": "text/xml" // If not specified, browser defaults will be used.
},
onload: function(response) {
/* use response here */
}
});
/* can't use response here */
without the fetchContent = console.log thing.
I am using jquery-localize plugin for translating my page. I wonder is it possible to load dynamically created JSON data (sent from server) instead of using pre-made files. It would be a lot easier to maintain since my web and desktop application share about 95% of text (so I am using same .resx file for both).
So, i loaded translations using ajax:
$.ajax({
type: "POST",
url: "Helper.aspx/LocalizePage",
data: '{"lang":"' + lang + '"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
if (msg.d != "error") {
console.log(msg.d);
translationData = msg.d;
var translationTable = jQuery.parseJSON(msg.d);
}
},
error: function (response) {
var responseTextObject = jQuery.parseJSON(response.responseText);
console.log(responseTextObject);
}
});
and i have parsed (translationTable) and unparsed (translationData) text. Unparsed is same as jquery-localize requires. So, how to use this data as source for it?
You can have your ajax/jquery reference a server side page that's written in php/asp or whatever preferred server side language. And then have that page return text in JSON format based on the criteria you pass to the page.
So, here is the solution. Bryant gave me idea what to do (load translation file via separate page) but it requires some modifications. First, we need to modify jquery-localize.js file. In localize function, alter switch so it looks like this:
switch (level) {
case 1:
intermediateLangData = {};
if (options.loadBase) {
//file = pkg + ("." + fileExtension);
file = pkg;
return jsonCall(file, pkg, lang, level);
} else {
return loadLanguage(pkg, lang, 2);
}
break;
case 2:
if (lang.length >= 2) {
//file = "" + pkg + "-" + (lang.substring(0, 2)) + "." + fileExtension;
file = pkg;
return jsonCall(file, pkg, lang, level);
}
break;
case 3:
if (lang.length >= 5) {
//file = "" + pkg + "-" + (lang.substring(0, 5)) + "." + fileExtension;
file = pkg;
return jsonCall(file, pkg, lang, level);
}
Notice commented original lines. We won't do any alterations of "filename" in my case, so be careful if you are doing your implementation (you might need to check requested language).
Other part of job is change how localization is initialized. Instead of standard $("[data-localize]").localize("filename"); we are going to use following line:
$("[data-localize]").localize("Localization.aspx?lang=en-US");
This Localize.aspx is dummy page which has following PageLoad event:
protected void Page_Load(object sender, EventArgs e)
{
string json = "";
var lang = Request.QueryString["lang"];
if (lang.Length > 0)
{
json = WebHelper.GetAllTranslations(lang);
}
else
{
json = WebHelper.GetAllTranslations("en-US");
}
Response.Clear();
Response.ContentType = "application/json; charset=utf-8";
Response.Write(json);
Response.End();
}
This WebHelper.GetAllTranslations(lang) returns JSON-formatted string with translations, just like you would have them in single file for regular use.
To sum up - instead of using file with translations, we modified jquery-localize.js so it loads translations directly from string, returned from page. This is simple and bit crude modification but it does it job.
Of course, you can use AJAX call or something else - important part is to modify jquery-localize that it doesn't search for files, but loads translation directly.
I hope this will help someone with similar problem.
I will start by saying that I am learning how to program in jquery/javascript, and am running into an issue using JSON.parse(). I understand the format, and why people use it... but have not been able to get it to work in any of my code projects.
I have read in books/online on here in how to use it, but I think I read too much on it. I am now confused and second guessing what I know about it.
With that said, my jquery/javascript class I am taking is asking me to use it for an assignment, through AJAX using MAMP/localhost as the server.
The two codes below are for the section that I need to fill in the //TODO information. One is javascript (client-side), the other is php (server-side). I think that I've set the other //TODO information correctly, but I keep getting a token error for the JSON part.
I looked on here for a solution, but again, I think I've confused myself badly and need help. Appreciate any feedback, insight, or information.
-Javascript-
var calculateMpg = function () {
// These lines are commented out since the server will perform these checks
// if (!checkNumber("miles") || !checkNumber("gallons")) {
// return;
// }
var miles = $("#miles").val();
var gallons = $("#gallons").val();
console.log("ajax request issued.");
var result;
$.ajax({
url: "service.php?action=calculateMPG&miles="+miles+"&gallons="+gallons,
cache: false,
dataType: "text",
success: function(msg) {
console.log("ajax response received.");
// TODO: parse the JSON string returned from the server (see JSON.parse())
JSON.parse("result");
if (result.status === 'success') {
// TODO: get the mpg value returned from the server and display it to the user.
$("#mpg").val($_GET("result"));
console.log("JSON Working!");
}
else {
// TODO: get the name of the variable with the error. Hint: look at the 'fail' result from service.php
$_GET[fail(id)];
// TODO: report the error to the user using invalidNumber() function.
alert("{status: 'failure', variable: <variable name>}");
}
}
});
};
$(document).ready( function () {
$("#miles").blur(function () {
checkNumber("miles");
});
$("#gallons").blur(function() {
checkNumber("gallons");
});
$("#calculate").click(calculateMpg);
$("#miles").focus();
});
-PHP-
<?php
if ($_GET) {
if ($_GET['action'] == 'calculateMPG') {
$miles = htmlspecialchars($_GET['miles']);
$gallons = htmlspecialchars($_GET['gallons']);
// validate miles
if (strlen($miles) == 0) {
fail("miles");
}
$miles_chars = str_split($miles);
for ($i=0; $i< count($miles_chars); $i++) {
if ($miles_chars[$i] < "0" || $miles_chars[$i] > "9") {
//error_log("miles_chars check failed at: " + $i);
fail("miles");
}
}
// validate gallons
if (strlen($gallons) == 0) {
fail("gallons");
}
$gallons_chars = str_split($gallons);
for ($i=0; $i< count($gallons_chars); $i++) {
if ($gallons_chars[$i] < "0" || $gallons_chars[$i] > "9") {
fail("gallons");
}
}
// validate $miles and $gallons calling $fail along the way
$result = $miles/$gallons;
if ($result) {
success($result);
} else {
fail("mpg");
}
exit ;
}
}
function fail($variable) {
die(json_encode(array('status' => 'fail', 'variable' => $variable)));
}
function success($message) {
die(json_encode(array('status' => 'success', 'message' => $message)));
}
Edited Additional 1
I have made changes to the JSON information in regard to 'var result' (thanks to several of the responses here). I'm starting to understand JSON a bit better.
Another question I have (now) is how to isolate a part of the JSON message from the whole being transmitted?
A piece of the 'JSON.parse(msg)' returned DOES include the answer to the equation miles/gallons, but I don't know how to... extract it from the JSON.
The solution to the equation miles/gallons appears in the 'msg' output.
Thanks.
Edited Additional 2
This question has been solved! While perusing around stackoverflow for a solution to the question in my previous edited section, I found my answer here: JSON response parsing in Javascript to get key/value pair.
The answer is this: under the //TODO section asking for the mpg value, I put the following code - $("#mpg").val(result.message); - which says that in the JSON section of the variable result, take the part of the JSON marked 'message', the value being the equation solution.
Thank you to all who responded with their solutions to my problem. I appreciate the fast responses, the great suggestions, and the information in understanding JSON.
-ECP03
JSON.parse() requires that you send it a valid JSON string.
"result" is not a valid JSON string. In your success function you have defined a parameter msg - what does this contain? Try console.log(msg) at the beginning of your success function and look at the console output.
You have two options:
Option 1: -- Parse the string returned.
Change JSON.parse("result"); to:
var result = JSON.parse( msg );
Option 2: -- Request JSON instead of plain text - no need to parse
Use $.getJSON() which is shorthand for:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
Instead of parsing the JSON yourself, jQuery already provides you with a convenient function that will parse JSON:
var path = "service.php?action=calculateMPG&miles="+miles+"&gallons="+gallons;
$.getJSON(path, function (data) {
if (data.status == 'success') {
console.log('Success! Message:', data.message);
} else {
console.log('Failed :( Variable:', data.variable);
}
});
For your original code, what you would need to do is call JSON.parse(msg) in your success callback, which would return a JavaScript object with the values you sent from your PHP script. By specifying dataType: 'json' in the $.ajax call, jQuery does this for you. The $.getJSON method does this and some other things for you.
You need to use the result returned by the success function:
var result = JSON.parse(msg);
Then, you could do stuff like result.status.
When you put JSON.parse("result") you're saying "parse the string 'result'," which doesn't make any sense. However, if you say JSON.parse(msg) you're saying "Parse the variable that was returned from the ajax action," which makes sense.
JSON.parse() is used to convert your json data to object, then you can manipulate it easly.JSON.parse(msg); instead of JSON.parse("result").
For example:
var json = '{"value1": "img", "value2":"img2"}'
var obj = JSON.parse(json);
for ( k in obj ) {
console.log(obj[k])
}
This is totally wrong: JSON.parse("result");. .parse() expects a JSON string, e.g. the string that came back from you ajax request. You're not providing that string. you're providing the word result, which is NOT valid JSON.
JSON is essentially the right-hand side of an assignment expression.e.g.
var foo = 'bar';
^^^^^---this is json
var baz = 42;
^^---also json
var qux = ['a', 'b', 'c'];
^^^^^^^^^^^^^^^---even more json
var x = 1+2;
^^^---**NOT** json... it's an expression.
What you're doing is basically:
var x = parse;
^^^^^^---unknown/undefined variable: not JSON, it's an expression
I know this is a long shot, but I'm trying to make a POST with AJAX within the Javascript tool in HPSM. It's got very limited debugging capabilities so I'm stuck where it should be simple (or so I thought). From the syntax I've seen in other articles, calling that AJAX function should be right, but it doesn't seem to want to take it.
Thanks for any help
Here is the code I'm calling, and using jQuery library v1.11.2
var JSONdata = {
"eId": "xxx111",
"deviceToken": "111111111111",
"deviceType": "iphone",
"applicationName": "huds"
};
system.library.jQuery.ajax({
type: "POST",
url: 'http://place:11400/location/collaboration/notifications/register/',
data: JSONdata,
dataType: "json",
cache: false,
crossDomain: true,
processData: true,
success: function (data) {
alert(JSON.stringify(data));
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error");
}
});
errors
Process panel calc.javascript in RAD format.cjavascript encountered error in line 5 (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Script <UNKNOWN> line 20: ERROR TypeError: system.library.jQuery.ajax is not a function at char 1
Script 'jQuery' line 925: ERROR TypeError: document has no properties at char 1
Unrecoverable error in application: se.call.process on panel call.rad.1
Unrecoverable error in application: cm.update.save on panel call.master.upd
Unrecoverable error in application: format.cjavascript on panel calc.javascript
I'm assuming you have a ScriptLibrary called jQuery in your HPSM, right?
Try with
lib.jQuery.ajax(...
instead of system.library, regards.
not sure if you have imported the jQuery as a ScriptLibrary, but I think it will not work, because the code inside the jQuery Library includes some lines of code which are not valid for the HPSM.
Anyway...
To call an external external RESTful Service, you can use the doHTTPRequest() function in your ScriptLibrary.
What it is, what parameters are needed etc. can be found in the Programming Guide:
http://86.48.81.222:6080/classic/Content/Resources/PDF/sm_programming_guide.pdf
See Page 266 ...
Here an short example how it should work (it calls the REST API from the HPSM to create a new incident:
var objConfig = {
"url" : "http://place:11400",
"path" : "/location/collaboration/notifications/register/",
"connect_timeout" : 30,
"read_timeout" : 30
};
var objPostData = {
"eId": "xxx111",
"deviceToken": "111111111111",
"deviceType": "iphone",
"applicationName": "huds"
};
createRecord( objPostData );
/**
* Create a new Incident with the RESTful API
*
* #param {Object} objRecord Object with all required fields
*
*/
function createRecord( objRecord ) {
var JSON = system.library.JSON.json();
var arrHeaders = [];
//Content Type application/json is required
//otherwise we will get an 501 error
var typeHeader = new Header();
typeHeader.name = "content-type";
typeHeader.value = "application/json";
var arrHeaders = new Array();
arrHeaders.push(typeHeader);
//build url for the request
//Default Action for POST is "create" so we don't need
//to add the action again
var cRequestUrl = objConfig.url+objConfig.path;
//convert the given object to an json string
cPostBody = system.library.JSON2.toJSON(objRecord);
try {
//lets run the the HTTP request
//HTTP Command - url to execute - http header - POST Body
var rcRequest = doHTTPRequest( "POST", cRequestUrl, arrHeaders, cPostBody, objConfig.connect_timeout, objConfig.read_timeout );
//convert response json string back to an object
var objResponse = JSON.parse(rcRequest);
print( objResponse.toSource() );
} catch( e ) {
//something goes wrong
//check also http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
//to get the description of the given http response code like 401 etc.
//currently it's not possible (or i don't know how) to get the correct
//error response - for me it looks like that the HPSM has an filter
//which removes the response body if the response header is not 200
//if it's possible to use the reponse, we can use the same code
//as above JSON.parse() etc.
print("ERROR: \n"+e);
}
}
INFO1: Currently there is a limitation in the doHTTPRequest.
It can't handle the catch case correctly.
So even when there is an error, you will get the response as string.
And not the Object or whatever the response is.
INFO2: This example is based on my example to call the internal incident api.
I have modified it to your given data.
Code was created and tested successfully with HPSM 9.3+.
Hope this helps.
Greets
Marcus