JSON error when trying to parse request length in loop - javascript

So I am trying to make a simple autocomplete form but keep getting a error when I try to test the program.
When I try to test the program my console spits out [11:25:26.267] SyntaxError: JSON.parse: unexpected character # /search.php:22 which is this line. I am pretty sure my syntax is fine but I could be mistaken. Any and all help would be most gratefully appreciated. Thank you to anyone who takes the time to read and/or answer even if you cannot help!
for (var i = 0; i < response.length; i++)
My Full code is as follows.
Edit: Now with page that echos the json. When I do console.log(req.responsetext) i get [11:38:04.967] ReferenceError: req is not defined. But i define req as a new xml request on window load so I am kind of stumped.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>Auto Complete</title>
</head>
<body>
<script>
window.onload = function () {
var req = new XMLHttpRequest(); //the HTTP request which will invoke the query
var input = document.getElementById('search'); //where to grab the search from
var output = document.getElementById('results'); //where to display the sugestions
input.oninput = getSuggestions;
function getSuggestions() {
req.onreadystatechange = function () {
output.innerHTML = ""; //CLEAR the previous results!! only once the server can process new ones though
if (this.readyState == 4 && input.value != "") {
var response = JSON.parse('(' + req.responseText + ')');
for (var i = 0; i < response.length; i++)
addSuggestion(response[i].terms);
}
}
req.open('GET', 'getterms.php?query=' + input.value, true); //GET request to getterms.php?=
req.send(null);
}
addSuggestion = function (suggestion) {
var div = document.createElement('div');
var p = document.createElement('p');
div.classList.add('suggestion'); //suggestion[x]...
p.textContent = suggestion;
div.appendChild(p);
output.appendChild(div);
div.onclick = function() {
input.value = p.innerHTML; //set the search box
getSuggestions(); //GET new suggesions
}
}
}
</script>
<input type='text' id='search' name='search' autofocus='autofocus'>
<div id='results'></div>
</body>
</html>
edit this is my php page that echos the json.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');
if (!isset($_GET['query']) || empty($_GET['query']))
header('HTTP/1.0 400 Bad Request', true, 400);
else {
$db = new PDO(
my database
);
$search_query = $db->prepare("
SELECT * FROM `words` WHERE `word` LIKE :keywords LIMIT 5
");
$params = array(
':keywords' => $_GET['query'] . '%',
);
$search_query->execute($params);
$results = $search_query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($results);
}
?>

Get rid of the ( and ) in the JSON.parse!
JSON.parse('(' + req.responseText + ')')
should be
JSON.parse( req.responseText );
hopefully the responseText is valid JSON

Related

Why do I get error when trying to parse this json object?

I have the following PHP (Codeigniter Frameword) code:
$webpages = $this->webpageModel->select('webpageID,webpageTitle')->where('webpagecategoryID', $webpagecategoryID)->findAll();
header('Content-Type: application/json');
echo json_encode(array("response" => $webpages))
In the console, this is what is displayed:
{"response":[{"webpageID":"3","webpageTitle":"\u03a7\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03c1\u03cc\u03b5\u03b4\u03c1\u03bf"}]}
This is my JavaScript:
$(document).ready(function() {
let category = $('#webpagecategoryID');
let webpage = $('#webpageID');
category.on('change', function(e) {
webpage.empty();
var req = new XMLHttpRequest();
req.open("GET", "<?php echo base_url(); ?>/backEnd/Ticker/webpages_from_selected_category/" + category.val(), false);
req.send();
let res = JSON.parse(req.response);
let response = res.response;
let len = Object.keys(response).length;
for (let i = 0; i < len; i++) {
let titleLength = 150;
var trimmedTitle = response[i]['webpageTitle'].substring(0, titleLength);
webpage.append("<option value=" + response[i]['webpageID'] + ">" + trimmedTitle + "</option>");
}
});
});
In the Javascript, when I try to parse the object, I get an error: Uncaught SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 2 column 1 of the JSON data
What I am doing wrong?
My problem has not been related with the JSON at all. I use CodeIgniter 4, which in the development environment post in the console the following tag:
<script type="text/javascript" id="debugbar_loader" data-time="1611742634" src="http://ea3.test/index.php?debugbar"></script><script type="text/javascript" id="debugbar_dynamic_script"></script><style type="text/css" id="debugbar_dynamic_style"></style>
after my JSON. And after I switch the environment to production, this script tag is not displayed in the console, and my code works just fine.

HTML page doesn't show that city does not exist

I am trying to make a website that shows the weather forecast. It already shows the weather forecast. If I want to enter a city that doesn't exist I want a message to appear. I already tried something with 404 but it doesn't show up in the console log. I hope someone can help me. Thank you in advance!
function getData() {
let apikey = 'private';
var city = document.querySelector('#city').value;
let requestURL = 'https://api.openweathermap.org/data/2.5/forecast?q='+city+'&appid='+apikey+'&units=metric';
let request = new XMLHttpRequest();
request.open('GET', requestURL, true);
request.responseType = 'json';
request.send();
request.onload = function () {
let data = request.response;
addData(data);
var body = document.querySelector('body');
var div = document.createElement('div');
for (var i = 0; i < data.list.length; i += 8) {
// console.log(data.list[i].dt_txt);
div.appendChild( createEL('p',
'<b>Date en time: ' + data.list[i].dt_txt+'<br></b>'+
'City: ' + city+'<br>'+
'Country: ' + data.city.country + '<br>'+
'Temperature: ' +data.list[i].main.temp+'<br>'+
'Weather: ' +data.list[i].weather[0].main));
}
if (XMLHttpRequest == '404'){
console.log("Doesn't exist")
}
var body = document.querySelector('body');
body.appendChild(div);
function createEL(tag, content){
var el = document.createElement(tag);
el.innerHTML = content;
return el;
}
}
}
var button = document.querySelector('#show');
button.addEventListener("click", function (ev) {
ev.preventDefault();
getData();
},false);
function addData(jsonData) {
var city = document.querySelector('#city').value;
var input = document.querySelector('#city');
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Weather</title>
</head>
<body>
<h1>Weather</h1>
City: <input type="text" id="city" name="city" placeholder="city">
<button id="show" name="show">Show</button>
<script src="js/weather.js"></script>
</body>
</html>
XMLHttpRequest will never be equal to 404. It is the constructor function you used to created the object that made the HTTP request!
You need to examine request.status.
You need to check request.status if you are sending status code from API.
let request = new XMLHttpRequest()
console.log(request.status);
To display does not exist you can check the response data length like
if(data.list.length==0)
{
console.log("Does not exists.");
}

AJAX return undefined in html document

I have the following xml document
<?xml version="1.0" ?>
<result searchKeyword="Mathematics">
<video>
<title>Chaos Game</title>
<channel>Numberphile</channel>
<view>428K</view>
<link>http://www.youtube.com/watch?v=kbKtFN71Lfs</link>
<image>http://i.ytimg.com/vi/kbKtFN71Lfs/0.jpg</image>
<length>8:38</length>
</video>
<video>
<title>Australian Story: Meet Eddie Woo, the maths teacher you wish you&apos;d had in high school</title>
<channel>ABC News (Australia)</channel>
<view>223K</view>
<link>http://www.youtube.com/watch?v=SjIHB8WzJek</link>
<image>http://i.ytimg.com/vi/SjIHB8WzJek/0.jpg</image>
<length>28:08</length>
</video>
<video>
<title>Ham Sandwich Problem</title>
<channel>Numberphile</channel>
<view>557K</view>
<link>http://www.youtube.com/watch?v=YCXmUi56rao</link>
<image>http://i.ytimg.com/vi/YCXmUi56rao/0.jpg</image>
<length>5:53</length>
</video>
<video>
<title>Magic Square Party Trick</title>
<channel>Numberphile</channel>
<view>312K</view>
<link>http://www.youtube.com/watch?v=aQxCnmhqZko</link>
<image>http://i.ytimg.com/vi/aQxCnmhqZko/0.jpg</image>
<length>3:57</length>
</video>
<video>
<title>The 8 Queen Problem</title>
<channel>Numberphile</channel>
<view>909K</view>
<link>http://www.youtube.com/watch?v=jPcBU0Z2Hj8</link>
<image>http://i.ytimg.com/vi/jPcBU0Z2Hj8/0.jpg</image>
<length>7:03</length>
</video>
</result>
I have created this html file which has an AJAX call to get the xml file but it return all the values as "undefined"
<html>
<head>
<title>A7-Question2</title>
<script>
function getSearch()
{
// create an XMLHttpRequest
var xhttp = new XMLHttpRequest();
//create a handler for the readyState change
xhttp.onreadystatechange = function() {
readyStateChangeHandler(xhttp);
};
//get XML file by making async call
xhttp.open("GET", "A7.xml", true);
xhttp.send();
}
// handler for the readyState change
function readyStateChangeHandler(xhttp){
if (xhttp.readyState == 4){
// readyState = 4 means DONE
if(xhttp.status == 200){
// status = 200 means OK
handleStatusSuccess(xhttp);
}else{
// status is NOT OK
handleStatusFailure(xhttp);
}
}
}
// XMLHttpRequest failed
function handleStatusFailure(xhttp){
// display error message
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}
// XMLHttpRequest success
function handleStatusSuccess(xhttp){
var xml = xhttp.responseXML;
// print XML on the console
console.log(xml);
// parse the XML into an object
var searchResult = parseXML(xml);
// print object on the console
console.log(searchResult);
// display the object on the page
display(searchResult);
}
// parse the XML into an object
function parseXML(xml){
var resultElement = xml.getElementsByTagName("result")[0];
//create a receipt object to hold the information in the xml file
var searchResult = {};
searchResult.searchKeyword= resultElement.getAttribute("searchKeyword");
var videoElements = xml.getElementsByTagName("video");
//create an array to hold the items
searchResult.videoArray = [];
for(var i=0; i< videoElements.length; i++){
var video = {};
video.title = videoElements[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
video.channel = Number(videoElements[i].getElementsByTagName("channel")[0].childNodes[0].nodeValue);
video.view = Number(videoElements[i].getElementsByTagName("view")[0].childNodes[0].nodeValue);
video.link = Number(videoElements[i].getElementsByTagName("link")[0].childNodes[0].nodeValue);
video.image = Number(videoElements[i].getElementsByTagName("image")[0].childNodes[0].nodeValue);
searchResult.videoArray.push(video);
};
return searchResult;
}
// display the searcg result object on the page
function display(searchResult){
var html = "<p>searchKeyword: Mathematics</p>";
for(var i=0; i<searchResult.videoArray.length; i++){
var video = searchResult.videoArray[i];
html += "title: " + searchResult.title + "<br/>";
html += "channel: " + searchResult.channel + "<br/>";
html += "view: " + searchResult.view + "<br/>";
html += "link: " + searchResult.link + "<br/>";
html += "image: " + searchResult.image + "<br/>";
html += "length: " + searchResult.length + "<br/>";
}
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = html;
}
</script>
</head>
<body>
<button onclick="getSearch()">Get Search Result</button>
<div id="display"></div>
</body>
</html>
Is the problem with my success function? Is it returning null because it hasn't returned all the values or something due to how AJAX runs?
Thanks heaps for any help
There's a lot of code to go over and a working snippet can't be produced because we can't put the XML file here.
This answer is making an assumption that your response from the XMLHttpRequest is null and the problem does not lie in any of your parsing functions.
It also seems that you're over complicating the request process by passing it around to many functions when it's quite simple itself.
Here is an example I made locally that correctly logged the XML to the console:
<!doctype html>
<html>
<head>
<title>A7-Questions2</title>
</head>
<body>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var xml = xhttp.responseXML;
// Logs just fine for me. You can do your parsing here.
console.log(xml);
}
};
xhttp.onerror = function() {
// Display error message.
var displayDiv = document.getElementById('display');
displayDiv.textContent = 'XMLHttpRequest failed status: ' + xhttp.status;
};
xhttp.open('GET', './path/to/xml.xml');
xhttp.send();
</script>
</body>
</html>

JSON error request is not defined

When I do console.log(req.responsetext) i get [11:38:04.967] ReferenceError: req is not defined. But i define req as a new xml request on window load so I am kind of stumped. Is there a way that I should be passing a reference?
the console output is as follows
[12:29:06.839] GET getterms.php?query=DFA [HTTP/1.1 200 OK 99ms]
[12:29:06.888] SyntaxError: JSON.parse: unexpected character # search.php:21
[12:33:24.316] console.log(req.responsetext)
[12:33:24.318] ReferenceError: req is not defined
Any and all help would be most gratefully appreciated. Thank you to anyone who takes the time to read and/or answer even if you cannot help!
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>Auto Complete</title>
</head>
<body>
<script>
window.onload = function () {
var req = new XMLHttpRequest(); //the HTTP request which will invoke the query
var input = document.getElementById('search'); //where to grab the search from
var output = document.getElementById('results'); //where to display the sugestions
input.oninput = getSuggestions;
function getSuggestions() {
req.onreadystatechange = function () {
output.innerHTML = ""; //CLEAR the previous results!! only once the server can process new ones though
if (this.readyState == 4 && input.value != "") {
var response = JSON.parse(req.responseText);
for (var i = 0; i < response.length; i++)
addSuggestion(response[i].terms);
}
}
req.open('GET', 'getterms.php?query=' + input.value, true); //GET request to getterms.php?=
req.send(null);
}
addSuggestion = function (suggestion) {
var div = document.createElement('div');
var p = document.createElement('p');
div.classList.add('suggestion'); //suggestion[x]...
p.textContent = suggestion;
div.appendChild(p);
output.appendChild(div);
div.onclick = function() {
input.value = p.innerHTML; //set the search box
getSuggestions(); //GET new suggesions
}
}
}
</script>
<input type='text' id='search' name='search' autofocus='autofocus'>
<div id='results'></div>
</body>
</html>
edit this is my php page that echos the json.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');
if (!isset($_GET['query']) || empty($_GET['query']))
header('HTTP/1.0 400 Bad Request', true, 400);
else {
$db = new PDO(
my database
);
$search_query = $db->prepare("
SELECT * FROM `words` WHERE `word` LIKE :keywords LIMIT 5
");
$params = array(
':keywords' => $_GET['query'] . '%',
);
$search_query->execute($params);
$results = $search_query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($results);
}
?>
Scope problem! Remove var in front of req to make it global and it should work

Post dynamic twitter updates

I currently have some script on my page that parses title/artist information from my online radio station. I am displaying it as plain text in html by using
<span id="song_title"></span>
How can I take this dynamic information that is going into the span id and use it for a "post to twitter" link so listeners can share the current song title on Twitter?
I did some research and found a few variations on posting to twitter, but I had no luck with posting this dynamic text.
Here's the script code:
<!-- Begin Now Playing Script -->
<script>
(function () {
// we need a JSON parser, if it does not exist, load it
if (typeof JSON == "undefined") {
var s = document.createElement("script");
// json2.js retrieved from https://github.com/douglascrockford/JSON-js
s.src = "json2.js";
document.getElementsByTagName("head").appendChild(s);
}
})();
var song_ends = 0;
function update_song () {
if ((new Date).getTime() < song_ends) {
// use cached result as the song has not ended yet
return;
}
var req = new XMLHttpRequest();
// IE compatbility:
var textContent = 'textContent' in document ? 'textContent' : 'innerText';
req.onreadystatechange = function () {
if (req.readyState == 4) {
var song = JSON.parse(req.responseText);
if (song.title) {
var img = document.getElementById("song_image");
if(song.image.src){
img.alt = song.image.alt;
img.src = song.image.src;
img.width = 100;
img.height = 100;
}else{
img.src="images/default_art.png";
img.width = 100;
img.height = 100;
}
document.getElementById("song_title")[textContent] = song.title ;
document.getElementById("song_artist")[textContent] = song.artist;
document.getElementById("song_next")[textContent] = song.next ;
// store the end date in javascript date format
song_ends = (new Date).getTime() + song.wait_ms;
}
}
};
req.open('get', 'php/PlayingNow.php', true);
req.send(null);
}
// poll for changes every 20 seconds
setInterval(update_song, 20000);
// and update the song information
update_song();
</script>
<!-- End Now Playing Script -->
I want to be able to post it to Twitter like this: Currently listening to (song_title) by (song_artist)
Here is the code for the PHP file referenced in the script above:
<?php // filename: PlayingNow.php
$json = null;
$cache = 'song.json';
// if there is no usuable cache
if (!$json) {
// retrieve the contents of the URL
$ch = curl_init('http://bigcountry.streamon.fm/card');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
curl_close($ch);
$json = json_decode($res);
// if the title exists, assume the result to be valid
if ($json && $json->title) {
// cache it
$fp = fopen('song.json', 'w');
fwrite($fp, $res);
fclose($fp);
} else {
$json = null;
}
}
if ($json) {
$info = array();
// contains the time in milliseconds
$info['wait_ms'] = $json->interval->ends_at - 1000 * microtime(true);
$info['title'] = $json->title ;
$info['artist'] = $json->artist;
$info['album'] = $json->album ;
$info['next'] = $json->next_song;
$info['image'] = $json->album_art;
// display a JSON response for the HTML page
echo json_encode($info);
}
?>
The "right" way to do this is to use Twitter's Web Intents, which is designed specifically for this scenario. Take a look at the "Tweet or Reply to a Tweet" section. In practice you'll just include the Web Intents script (http://platform.twitter.com/widgets.js) on your page, create a link, and set its href, e.g.:
var link = document.createElement('a');
link.innerHTML = "Link Text";
link.href = 'http://twitter.com/intent/tweet?text=Currently listening to "' + songTitle + '" by ' + songArtist;
var parentElement = document.getElementById('SOME_ELEMENTS_ID');
parentElement.appendChild(link);
You can add the url parameter if you also want the tweet to include your site's URL.

Categories

Resources