I am totally new to JavaScript, trying to get JSONP geocoding data from geocoding.geo.census.gov into a website. The response looks something like that (from chrome), only the first few keys are shown:
JSONPCallback({"result":{"input":{"address":{"address":"333 e 33th st austin tx"},"vintage":{"isDefault":true,"vintageName":"Current_Current","id":"4","vintageDescription":"Current Vintage - Current Benchmark"},"benchmark":{"isDefault":false,"id":"4","benchmarkName":"Public_AR_Current","benchmarkDescription":"Public Address Ranges - Current Benchmark"}}...............
This is the code I'm using:
var jsonp = {
callbackCounter: 0,
fetch: function(url, callback) {
var fn = 'JSONPCallback_' + this.callbackCounter++;
window[fn] = this.evalJSONP(callback);
url = url.replace('=JSONPCallback', '=' + fn);
var scriptTag = document.createElement('SCRIPT');
scriptTag.src = url;
document.getElementsByTagName('HEAD')[0].appendChild(scriptTag);
},
evalJSONP: function(callback) {
return function(data) {
var validJSON = false;
if (typeof data == "string") {
try {validJSON = JSON.parse(data);} catch (e) {
/*invalid JSON*/}
} else {
validJSON = JSON.parse(JSON.stringify(data));
window.console && console.warn('response data was not a JSON string');
}
if (validJSON) {
callback(validJSON);
} else {
throw("JSONP call returned invalid or empty JSON");
}
}
}
}
then:
{console.log(Object.keys(data));} //(or data[0])
and all I'm getting in the console is:
response data was not a JSON string
Array[1]0: "result"
length: 1
proto: Array[0]
I don't understand why all I'm getting is just "result"?
evalJSONP: function(callback) {
return callback;
}
That should work. If your sample is accurate. Then you don't need to parse the data.
I believe the old code wasn't working because it was trying to parse an object. Plase correct me if I'm wrong.
Related
Hi I'm trying to create a rest response using post method, I want to dynamically pass the variables instead of hard coding,But where i fail is,when I'm trying to to send an array as a parameter to the Rest web service using post method(example array ["CN=XXX_XX,OU=XXXXX,OU=1_XXXX XXXXity Groups,DC=XXXX,DC=local"]) and I know that there is a better way to do that Please find my code sample.This is the method that gives me a appropriate result.
First Method:(Works)
`
try {
var r = new sn_ws.RESTMessageV2('SailPoint_IdM', 'post');
var txt = "{\r\n\t\"workflowArgs\":\r\n\t{\r\n\t\"identityName\":\"SiamR\",\r\n\t\"appName\":\"Active Directory\",\r\n\t\"listEntitlements\":[\"CN=ER_CxxxK,OU=xxxxx,OU=1_xxxxxx Security xxx,DC=xxxx,DC=local\"],\r\n\t\"operation\":\"Add\",\r\n\t\"ticketNumber\":\"RITM1234567\"\r\n\t}\r\n}";
r.setRequestBody(txt);
var response = r.execute();
var ResponseBody = response.getBody();
var HTTPCode = response.getStatusCode();
gs.log(ResponseBody);
gs.log(HTTPCode);
} catch (ex) {
var message = ex.getMessage();
}
output:
Script: {"attributes":{"requestResult":{"status":"Success"}},"complete":false,"errors":null,"failure":false,"metaData":null,"requestID":"2c988d8c5bd47cf7015bebfb64cf01e6","retry":false,"retryWait":0,"status":null,"success":false,"warnings":null}
Script: 200
2n Method (Does not Work):
try {
var r = new sn_ws.RESTMessageV2('SailPoint_IdM', 'post');
r.setStringParameter('"listEntitlements"', '["CN=Exxx_xxxK,OU=xxxxion,OU=1_xxxxx Security xxxx,DC=xxx,DC=xxxx"]');
r.setStringParameter('"identityName"', '"SiarmR"');
r.setStringParameter('"appName"', '"Active Directory"');
r.setStringParameter('"ticketNumber"', '"RITM1234567"');
r.setStringParameter('operation', '"Add"');
//override authentication profile
//authentication type ='basic'/ 'oauth2'
//r.setAuthentication(authentication type, profile name);
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
gs.log(responseBody );
}
catch(ex) {
var message = ex.getMessage();
}
output:
Script: {"attributes":{"requestResult":{"errors":["An unexpected error occurred: sailpoint.tools.GeneralException: The application script threw an exception: java.lang.NullPointerException: Null Pointer in Method Invocation BSF info: script at line: 0 column: columnNo"],"status":"FAIL","GroupStatus":null,"AppStatus":null}},"complete":false,"errors":["Status : failed\nAn unexpected error occurred: sailpoint.tools.GeneralException: The application script threw an exception: java.lang.NullPointerException: Null Pointer in Method Invocation BSF info: script at line: 0 column: columnNo\n"],"failure":false,"metaData":null,"requestID":null,"retry":false,"retryWait":0,"status":null,"success":false,"warnings":null}
Script: 200
Im facing issue with this parameter as im trying to pass this as aray paramenter '["CN=Exxx_xxxK,OU=xxxxion,OU=1_xxxxx Security xxxx,DC=xxx,DC=xxxx"]'
Please suggest a way to implement this and to pass all the variables dynamically if suggesting first method
Below is one of my function, to handle dynamic parameters in either appear in request endpoint (url), headers or body;
For eg: parameter p
var p = {abc: 'def'};
and outbuond rest settings:
rest url = https://xxxx.sss.com/api/showme?name=${abc}
rest headers name = custom-header; value = ${abc}
rest body = {name: "${abc}"}
so it will replace all ${abc} to 'def'
_.isNullOrEmpty - check is obj, string or array is null or empty;
_.loop - loop an obj or array, pass in function(nm/i, val) {}
_.isArray - to check if is array
_.str - convert anything to string
_.rpl - replace all string A to B
restParameters: function (restRequest, obj, endpoint) {
var _ = this;
if ((_.isNullOrEmpty(restRequest)) || (_.isNullOrEmpty(obj))) return;
if (_.isNullOrEmpty(endpoint)) endpoint = restRequest.getEndpoint();
var body = restRequest.getRequestBody();
var headers = restRequest.getRequestHeaders();
_.loop(obj, function(nm, val) {
if (_.isArray(val)) {
val = (_.isNullOrEmpty(val)) ? '[]' : JSON.stringify(val);
} else val = _.str(val);
//for my case my array pass in as string become: "[\"1\", \"2\"]"
//comment below if pass in as object
if (val.contains('"')) val = _.rpl(val, '"', '\\"');
restRequest.setStringParameterNoEscape(nm, val);
var sch = '${' + nm + '}';
endpoint = _.rpl(endpoint, sch, val);
body = _.rpl(body, sch, val);
_.loop(headers, function (hn, hv) {
headers[hn] = _.rpl(hv, sch, val);
});
}, true);
restRequest.setEndpoint(endpoint);
restRequest.setRequestBody(body);
_.loop(headers, function (hn, hv) { restRequest.setRequestHeader(hn, hv); });
}
I am querying Splunk using javascript SDK. In the searchParams, i have given the output mode as "json_rows".
var searchParams = {
exec_mode: "normal",
output_mode: "json_rows"
};
But still when i get the output, i don't get it in a JSON format. The output is coming as an array.
Any idea what is going wrong? I tried "json_cols" and only "json" also. Same result.
Thanks in advance.
Edit:2
Some more of the code
var service = new splunkjs.Service({
username:"xxx",
password:"xxxx",
scheme:"https",
host:"xxxxxx.com",
port:"5500",
version:"5.0"
});
var searchQuery = 'search index=sn impact=1 OR impact=2 | eval time = round( strptime(impact_start,"%Y-%m-%d %H:%M:%S"), 0 )| where time >= ' + 14334627 + ' AND time<=' + 14568862 + '| bucket time span=1d | stats values(number) as incident_name by time';
var searchParams = {
exec_mode: "normal",
output_mode: "JSON"
};
service.oneshotSearch(
searchQuery,
searchParams,
function(err, results) {
if ( results ) {
var incidentResp = {};
incidentResp["data"] = results.rows;
incidentResp["error"] = null;
callback(null, incidentResp);
return;
}
else {
var errResp = {};
errResp["data"] = null;
errResp["error"] =err;
callback(null, errResp);
return;
}
}
);
I'm not 100% sure what you're asking, but let me try to help.
output_mode just tells the REST API how to serialize and return the results, usually either JSON, XML, or CSV
Given you're using the JavaScript SDK to pull data into your application and not actually having the results written to file, I would leave this as is (JSON default)
You'll find the actual data in the 'results' of the response.
eg.
service.oneshotSearch( query, params,
function(err, response) {
if (err) throw new Error ( err );
console.log( response.results );
});
Try changing this line:
incidentResp["data"] = results.rows;:
To this:
incidentResp["data"] = results.results;
... but yes, this will be an array of results.
Hope this helps
Take Parse Javascript SDK 1.6.4 for example,
from line 179:
_CoreManager2['default'].setCloudController({
run: function run(name, data, options) {
var RESTController = _CoreManager2['default'].getRESTController();
var payload = (0, _encode2['default'])(data, true);
var requestOptions = {};
if (options.hasOwnProperty('useMasterKey')) {
requestOptions.useMasterKey = options.useMasterKey;
}
if (options.hasOwnProperty('sessionToken')) {
requestOptions.sessionToken = options.sessionToken;
}
var request = RESTController.request('POST', 'functions/' + name, payload, requestOptions);
return request.then(function (res) {
var decoded = (0, _decode2['default'])(res);
if (decoded && decoded.hasOwnProperty('result')) {
return _ParsePromise2['default'].as(decoded.result);
}
return _ParsePromise2['default'].error(new _ParseError2['default'](_ParseError2['default'].INVALID_JSON, 'The server returned an invalid response.'));
})._thenRunCallbacks(options);
}
});
The _decode2['default'] uses fromJSON for Parse Object from line 4144:
key: 'fromJSON',
value: function fromJSON(json) {
if (!json.className) {
throw new Error('Cannot create an object without a className');
}
var constructor = classMap[json.className];
var o = constructor ? new constructor() : new ParseObject(json.className);
var otherAttributes = {};
for (var attr in json) {
if (attr !== 'className' && attr !== '__type') {
otherAttributes[attr] = json[attr];
}
}
o._finishFetch(otherAttributes);
if (json.objectId) {
o._setExisted(true);
}
return o;
}
I passed a full Parse object in my cloud code run success callback, but this decoding behavior purges my returning Parse object into a object reference.
Why do we want to have this?
Is there a option to get full object instead of a reference?
What I want is to get an updated object to update my view on success.
I am having an issue trying to improve the functionality of my ajax functions by adding arguments to define what to do with the returned result.
So what i am trying to implement is a way to tell the function to append the result to a given element by its id. But i am having difficulty understanding how to add this functionality.
This is my current code:
var ajax = new function(){
var self = this;
self.x = function() {
if (typeof XMLHttpRequest !== 'undefined') {
return new XMLHttpRequest();
}
};
self.send = function(url, callback, method, data, sync) {
var x = self.x();
x.open(method, url, sync);
x.onreadystatechange = function() {
if (x.readyState == 4) {
callback(x.responseText)
}
};
if (method == 'POST') {
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
x.send(data)
};
self.get = function(url, data, callback, sync) {
var query = [];
for (var key in data) {
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
self.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, sync)
};
};
I then make an ajax request like so:
//get the html file, and then call a function
ajax.get(dir.layout+'login.html',false,
function(){
elements.addTemplate(data,'parent',true);
});
In Chrome the xhr shows the correct data and contents, so i know that part works. In my elements.loadTemplate function i have these three lines with their actual values:
elements.addtemplate(data,div_id,append){
console.log(data); //shows:
console.log(div_id); //shows string: parent
console.log(append); //shows: true
}
Now the issue is data is blank, when i want it to contain the contents of the HTML file that I just requested (in this case login.html). I am wondering why it would show up as blank and how i can fix it?
your data is undefined because your callback doesn't accept a parameter
try this:
ajax.get(dir.layout+'login.html',false,
function(data){ // <=== data
elements.addTemplate(data,'parent',true);
});
I have json data with "tagged" values (from a jsonp source):
{"foo": "#duration:8542"}
which I can parse on-the-fly by passing a function as the second argument to JSON.parse:
dk.json = {
parse: function (s) {
return JSON.parse(s, function (key, val) {
if (typeof val === 'string' && val[0] === '#') {
var colonpos = val.indexOf(':');
if (colonpos > 1) {
var tag = val.slice(0, colonpos + 1);
switch (tag) {
case dk.Date.tag: return dk.Date.create(val);
case dk.Duration.tag: return dk.Duration.create(val);
}
}
}
return val;
});
},
//...
};
but how can I plug this parsing function into jQuery.ajax()? Something more sensible than:
success: function (data) {
data = dk.json.parse(JSON.stringify(data));
...
dataFilter, and especially converters looked promising:
$.ajax({
dataType: 'jsonp',
converters: {
'text json': dk.json.parse
},
// ...
});
but that doesn't get called at all (dataFilter gets called, but with the data parameter set to undefined).
Where am I going wrong?
[Edit:]
I know I can write a traversal function that walks the JSON object returned by jQuery, eg:
function untag(val) {
if (typeof val === 'string' && val[0] === '#') {
var colonpos = val.indexOf(':');
if (colonpos > 1) {
var tag = val.slice(0, colonpos + 1);
switch (tag) {
case dk.Date.tag: return dk.Date.create(val);
case dk.Duration.tag: return dk.Duration.create(val);
}
}
}
return val;
}
var untag_json = function (jsonobj) {
var _traverse = function _traverse(obj, result) {
var value;
for (var attr in obj) {
value = obj[attr];
if (value && typeof value === 'object') {
result[attr] = _traverse(value, {});
} else {
result[attr] = untag(value);
}
}
return result;
};
return _traverse(jsonobj, {});
};
and then call it in the success handler:
success: function (data) {
data = untag_json(data);
...
but that seems like a lot of unnecessary work.. Is there no way to use the converters parameter to $.ajax to get access to the unparsed (i.e. text) json source?
There actually isn't any JSON parsing in a JSONP request (src), which can seem counter intuitive. What is happening is the string that is returning from the JSONP endpoint is evaluated as JavaScript (with a reference to a function that is defined (or added in dynamically) in the DOM making the JSONP request like this:
_callback({'foo':'#duration:8524'});
If you wanted to use your function you would need to make the endpoint return a String like this:
_callback("{'foo':'#duration:8524'}");
then in the JSONP callback you could call JSON.parse(). JSON parse is a rather safe way to process JSON so if this was easier to reason about then it would be a fine approach.
Hi you need to set this header application/json in the response from server side then you can simply set dataType:json or dataType:jsonp then you will not need to stringify or parse the json. You then just get objects, properties or arrays from json.
For example : in php we use
$json_string = "{"foo": "#duration:8542"}";
$json = json_decode($json_string);
$foo = $json->foo;
echo $foo;//prints #duration:8542
In jquery you can do this:
sucess:function(response) {
var foo = response.foo;
console.log(foo);
}
Hope this helps