Google Script: JSON.parse fails for no apparent reason - javascript

I have this function in google script that fetches a JSON from the web, but it fails when i try to execute it, citing:
SyntaxError: Unexcpected character in string: '\''
Script:
function getTheFeed(url){
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var Jdata = JSON.parse(json);
Jdata = json;
return Jdata;
}
I've tested the URL, by importing it in a string and doing JSON.parse on it, and i get no errors in Google Chrome.
Any other ideas?
UPDATE: After doing Logger.Log turns out the JSON is being cut after 8KB of response. Nothing conflicting at the place the request ends...
Still looking for a response...

Try to use alert(url) and see what you really get.
It could be an escaping issue which sometimes browsers handle properly when you enter it directly in the address bar.
EDIT:
Different browsers have different limits. But generally the limit is around 2,000 characters for the GET method of a URL.
See:
What is the character limit on URL

Related

Parsing JSON from a file path is not working properly

I am trying to parse a list of JSON files iteratively. Using PHP I have managed to compile the list of JSON files in a directly into a a single JSON object. Now I would like to parse each of these objects and output a property from each of them in HTML. I am sure that the JSON I am initially passing works. Any ideas? here is the error and the function.
$(document).ready(function(){
console.log("something")
for(var i = 2; i < Object.keys(jsTrips).length; i++){
var data_file = "http://localhos:8080/trips/" + jsTrips[i];
var currTrip = JSON.parse(data_file)
document.getElementsByClassName(i).innerHTML = currJSON.start_time;
}
console.log("finished")
});
ignore the missing t in localhost. The problem persists even when the typo is fixed
Thanks in advance!!
UPDATE:
The Javascript object jsTrips is formatted like this:
{2: name.json, 3:name.json, 4:name.json}
The the JSON files named in jsTrips are formatted like this:
{start_time: some start time, coords: [{lat: ##, long: ##}, {lat: ##, long: ##}...], end_time: some end time}
To address the error you see:
SyntaxError: JSON.parse: Unexpected character at Line 1 Column 1
The JSON.parse() method parses a JSON string, constructing the JavaScript value or object described by the string. You are feeding it a URL when it is expecting [ or { as the first character. So h causes a Syntax Error.
Assuming you define the Object jsTrips someplace in your code, and this is a more basic object, I would suggest the following:
$(function(){
console.log("Start jsTrips");
var i = 0;
$.each(jsTrips, function(k, v){
if(i >= 2){
$.getJSON("http://localhos:8080/trips/" + v, function(data_file){
$("." + i).html(data_file.start_time);
});
}
i++;
}
console.log("Finished");
});
This code also assumes there are HTML Elements with attributes like class="2". It would be better to update your Post with an example of the Objects and an example of the JSON being returned.
Now, if the Index of the Object is the class name, then it might look more like:
$.getJSON("http://localhos:8080/trips/" + v, function(data_file){
$("." + k).html(data_file.start_time);
}
Again, need to know what you're sending and what you expect to get back.
jQuery.getJSON() Load JSON-encoded data from the server using a GET HTTP request.
See More: https://api.jquery.com/jquery.getjson/
Update
Now using JSONP method via $.getJSON(), this will help address CORS:
$(function() {
var jsTrips = {
2: "file-1.json",
3: "file-2.json",
4: "file-3.json"
};
console.log("Start jsTrips");
$.each(jsTrips, function(k, v) {
var url = "http://localhos:8080/trips/" + v;
console.log("GET " + url);
$.getJSON(url + "?callback=?", function(json) {
$("." + k).html(json.start_time);
});
});
console.log("Finished");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
As you can see, this builds the new URL from your jsTrips as expected. You can get the start_time from the JSON directly. You don't need to parse it when JSON is expected.
In regards to the new CORS issue, this is more complicated. Basically, you're not calling the same URI so the browser is protecting itself from outside code.
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
An example of a cross-origin request: The frontend JavaScript code for a web application served from http://domain-a.com uses XMLHttpRequest to make a request for http://api.domain-b.com/data.json.
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request HTTP resources from the same origin the application was loaded from, unless the response from the other origin includes the right CORS headers.
See more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS & https://www.sitepoint.com/jsonp-examples/
If you are unable to change the port being used for the target JSON files, which I suspect is creating the CORS issue, you can consider using JSONP method versus GET method. Comment and let me know if this is the case, and I can update the answer. Example included in update.
Hope that helps.
This will not probably be a complete answer, because I don't really understand the question. But maybe it will help.
You told us you compiled in PHP one file from several JSON files, in general, if you have object in JSON file, it will look like { ...some key-values here... }, if you have array there, it will be [ ...some key-values here... ].
So when you compile several files with objects into one, you'll get {...some key-values here...} {...some key-values here...} and JSON does not know how to parse those, it will throw error:
console.log(JSON.parse('{"key": "value"}{"key": "value"}'))
This will work just fine, only one object there:
console.log(JSON.parse('{"key": "value"}'))
So, if for some reason you really need to compile several JSON files into one, there is a solution - to make such resulting file with new lines as separators. Than in JS you can split your file by new line, and parse each line without issues.
Like so:
const arrayOfJSONs = Array(10).fill(null).map((_,i) => JSON.stringify({key: i, keyXTen: i * 10}))
// then you join them in one big file with \\n new lines as separators
const oneBigFile = arrayOfJSONs.join("\n");
console.log("oneBigFile:\n", oneBigFile)
// on the client you get your one big file, and then parse each line like so
const parsedJSONs = oneBigFile.split("\n").map(JSON.parse)
console.log("parsedJSONs\n", parsedJSONs)
JSON.parse take string input
Javacript fetch
$(document).ready(function(){
console.log("something")
for(var i = 2; i < Object.keys(jsTrips).length; i++){
var data_file = "http://localhos:8080/trips/" + jsTrips[i];
fetch(data_file).then((res) => res.json())
.then((currJSON) => {
// document.getElementsByClassName(i).innerHTML = currJSON.start_time;
// update your DOM here
})
}
console.log("finished")
});
JQuery $.getJSON
$(document).ready(function(){
console.log("something")
for(var i = 2; i < Object.keys(jsTrips).length; i++){
var data_file = "http://localhos:8080/trips/" + jsTrips[i];
$.getJSON(data_file, (currJSON) => {
// document.getElementsByClassName(i).innerHTML = currJSON.start_time;
// Update DOM here
});
}
console.log("finished")
});

How to add an API Key to a UrlFetchApp in Google Apps Scripts

Solved
Thanks to Dimu Designs for helping out.
The following works.
function myFunction() {
var url = "https://api.fortnitetracker.com/v1/profile/pc/Ninja"; var apiKey = "xxx-xxx-xxx";
var res = UrlFetchApp.fetch(
url,
{
"headers":{
"TRN-Api-Key":apiKey
}
} ); var content = res.getContentText(); Logger.log(res); Logger.log(content);
}
Problem
I'm trying to use Google App Scripts within Google Sheets to call the external Fortnite API to request player data. The bit I'm stuck on how to add an API Key as a header when passing the request.
This is what I've built so far (please no laughing)!...
function myFunction() {
var res =
UrlFetchApp.fetch("https://api.fortnitetracker.com/v1/profile/PC/Ninja?");
var content = res.getContentText(); Logger.log(res);
Logger.log(content);
}
When I try to run this I get back the following error:
Request failed for
https://api.fortnitetracker.com/v1/profile/PC/Ninja? returned code
401. Truncated server response: {"message":"No API key found in request"} (use muteHttpExceptions option to examine full response
I've tried adding my API key in a number of ways based on a number of different posts, but it doesn't work and just confuses me even more (easily done at this point).
Does anyone have any idea how I could go about completing the script to ensure I get information back? :)
---Edit---
First of all, thanks for the help guys, here's where we are at the moment. I've now tried the following:
var url = "https://api.fortnitetracker.com/v1/profile/pc/Ninja"; var apiKey = "xxx-xxxx-xxx";
var response = UrlFetchApp.fetch(
url,
{
"headers":{
"TRN-Api-Key":apiKey
}
} );
Rather than a 401 error, this time a 403 error is being returned.
Note, I've also tried to authenticate the header using "basic" but that doesn't work".
EDIT
I suspect that the API uses a custom header. When you register for an API key you get a string in the following form:
TRN-Api-Key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
I'm guessing here, but the text preceding the colon appears to be a custom header and the string of characters after the colon is the API key.
Without proper documentation this is STILL pretty much a shot in the dark but you can try the following:
var url = "[FORTNITE-API-ENDPOINT]";
var apiKey = "[YOUR-API-KEY]"; // sans header and colon
var response = UrlFetchApp.fetch(
url,
{
"headers":{
"TRN-Api-Key":apiKey
}
}
);
Also, make sure to check out the UrlFetchApp documentation for future reference:
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app

JavaScript JSON.parse UTF-8 problems

I have a page that makes a request to a php file via AJAX, and that AJAX file displays a JSON which is the response, and I've got some issues with it.
It results that my page uses UTF-8 charset in order to display some special chars, etc; my AJAX file used ANSI encoding by default but then I decided to change it to UTF-8 to get the correct symbols with it too, but when I use JSON.parse it throws me the error "Uncaught SyntaxError: Unexpected token", (if the AJAX file is encoded as UTF-8), then I change to ANSI
and it works great, I don't know why JSON has that behaviour.
When I look at the output (xhr.responseText) both from ANSI and UTF-8 are identical (I'm not even using special chars in UTF-8).
Maybe JSON.parse doesn't accept response from UTF-8 files (something that I don't believe) or do I have to set a header in order to fix that? What do you guys think about it? Thank you..
I had faced same problem. I used following encode functions instead of default encode function. It gives me perfect result
function json_encode_utf8($arr) {
array_walk_recursive($arr, 'encode_utf8');
return mb_decode_numericentity(json_encode($arr), array(0x80, 0xffff, 0, 0xffff), 'UTF-8');
}
function encode_utf8(&$item, $key) {
if (is_string($item))
$item = mb_encode_numericentity($item, array(0x80, 0xffff, 0, 0xffff), 'UTF-8');
}
$group_members = array('Matthias Schöbe');
$group_members_json = json_encode_utf8($group_members);

I keep getting "Uncaught SyntaxError: Unexpected token o"

I'm trying to learn some html/css/javascript, so I'm writing myself a teaching project.
The idea was to have some vocabulary contained in a json file which would then be loaded into a table. I managed to load the file in and print out one of its values, after which I began writing the code to load the values into the table.
After doing that I started getting an error, so I removed all the code I had written, leaving me with only one line (the same line that had worked before) ... only the error is still there.
The error is as follows:
Uncaught SyntaxError: Unexpected token o
(anonymous function)script.js:10
jQuery.Callbacks.firejquery-1.7.js:1064
jQuery.Callbacks.self.fireWithjquery-1.7.js:1182
donejquery-1.7.js:7454
jQuery.ajaxTransport.send.callback
My javascript code is contained in a separate file and is simply this:
function loadPageIntoDiv(){
document.getElementById("wokabWeeks").style.display = "block";
}
function loadWokab(){
//also tried getJSON which threw the same error
jQuery.get('wokab.json', function(data) {
var glacier = JSON.parse(data);
});
}
And my JSON file just has the following right now:
[
{
"english": "bag",
"kana": "kaban",
"kanji": "K"
},
{
"english": "glasses",
"kana": "megane",
"kanji": "M"
}
]
Now the error is reported in line 11 which is the var glacier = JSON.parse(data); line.
When I remove the json file I get the error: "GET http://.../wokab.json 404 (Not Found)" so I know it's loading it (or at least trying to).
Looks like jQuery takes a guess about the datatype. It does the JSON parsing even though you're not calling getJSON()-- then when you try to call JSON.parse() on an object, you're getting the error.
Further explanation can be found in Aditya Mittal's answer.
The problem is very simple
jQuery.get('wokab.json', function(data) {
var glacier = JSON.parse(data);
});
You're parsing it twice. get uses the dataType='json', so data is already in json format.
Use $.ajax({ dataType: 'json' ... to specifically set the returned data type!
Basically if the response header is text/html you need to parse, and if the response header is application/json it is already parsed for you.
Parsed data from jquery success handler for text/html response:
var parsed = JSON.parse(data);
Parsed data from jquery success handler for application/json response:
var parsed = data;
Another hints for Unexpected token errors.
There are two major differences between javascript objects and json:
json data must be always quoted with double quotes.
keys must be quoted
Correct JSON
{
"english": "bag",
"kana": "kaban",
"kanji": "K"
}
Error JSON 1
{
'english': 'bag',
'kana': 'kaban',
'kanji': 'K'
}
Error JSON 2
{
english: "bag",
kana: "kaban",
kanji: "K"
}
Remark
This is not a direct answer for that question. But it's an answer for Unexpected token errors. So it may be help others who stumple upon that question.
Simply the response is already parsed, you don't need to parse it again. if you parse it again it will give you "unexpected token o" however you have to specify datatype in your request to be of type dataType='json'
I had a similar problem just now and my solution might help. I'm using an iframe to upload and convert an xml file to json and send it back behind the scenes, and Chrome was adding some garbage to the incoming data that only would show up intermittently and cause the "Uncaught SyntaxError: Unexpected token o" error.
I was accessing the iframe data like this:
$('#load-file-iframe').contents().text()
which worked fine on localhost, but when I uploaded it to the server it stopped working only with some files and only when loading the files in a certain order. I don't really know what caused it, but this fixed it. I changed the line above to
$('#load-file-iframe').contents().find('body').text()
once I noticed some garbage in the HTML response.
Long story short check your raw HTML response data and you might turn something up.
SyntaxError: Unexpected token o in JSON
This also happens when you forget to use the await keyword for a method that returns JSON data.
For example:
async function returnJSONData()
{
return "{\"prop\": 2}";
}
var json_str = returnJSONData();
var json_obj = JSON.parse(json_str);
will throw an error because of the missing await. What is actually returned is a Promise [object], not a string.
To fix just add await as you're supposed to:
var json_str = await returnJSONData();
This should be pretty obvious, but the error is called on JSON.parse, so it's easy to miss if there's some distance between your await method call and the JSON.parse call.
Make sure your JSON file does not have any trailing characters before or after. Maybe an unprintable one? You may want to try this way:
[{"english":"bag","kana":"kaban","kanji":"K"},{"english":"glasses","kana":"megane","kanji":"M"}]
const getCircularReplacer = () => {
const seen = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
JSON.stringify(tempActivity, getCircularReplacer());
Where tempActivity is fething the data which produces the error "SyntaxError: Unexpected token o in JSON at position 1 - Stack Overflow"

Json object in jquery can't be read?

I am trying to read the finance info from the google page into a json object.
Code is below:
try {
$.getJSON("http://finance.google.com/finance/info?client=ig&q=NSE:GOLDBEES&jsoncallback=?",function(data){
alert(data);//var jsondata = data;
//jsonobj = $.parseJSON(jsondata);
//alert(jsonobj[0].id);
});
} catch(e) {
alert(e.toString());
}
However I keep getting this error all the time on firebug
invalid label
"id": "4052464"
Is there any way this info can be read. My ultimate goal is to create a windows 7 gadget that doesnt use server side scripting and can be used from any Windows 7 system.
Appreciate all the help.
John
Response isn't valid JSON (response is prefixed with //), so jQuery won't be able to parse it correctly anyway.
To solve change &jsoncallback=? to &callback=?
so
$.getJSON("http://finance.google.com/finance/info?client=ig&q=NSE:GOLDBEES&callback=?", function(data) {
alert(data)
});
The response from Google has two leading /'s, making the response invalid JSON... for some reason.
Because of this, you cannot use jQuery.getJSON, as it expects a JSON response. Instead, you should use jQuery.get, and parse the JSON yourself after removing the two leading slashes.
jQuery.get('http://finance.google.com/finance/info?client=ig&q=NSE:GOLDBEES&jsoncallback=?', function (string) {
var validJson = string.slice(2);
var obj = jQuery.parseJSON(validJSON);
// use obj
});
Two additional points:
No JSONP is being used, so you don't need the jsoncallback=? in your request URL
The Windows Sidebar has been retired, so you cannot publish you finished gadget to the official gallery.

Categories

Resources