xhr.responseText isn't converted to object by JSON.parse() - javascript

I have written this function to make ajax-requests to my server that serves JSON objects in string-format. I want to parse these JSON-objects into Javascript objects using JSON.parse(). But when I check the type of the object returned by JSON.parse(), it's a string! Here's the function:
function getDBMatches(){
var xhr = createXHR();
xhr.dropdown = this.parentNode.parentNode.getElementsByClassName("dropdown-content")[0];
xhr.dropdown.innerHTML = "";
if(!xhr.dropdown.classList.contains('show')){
xhr.dropdown.classList.add('show');
}
xhr.onreadystatechange = function(){
if (this.value == ""){
return;
}
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
var xhrResponse = xhr.responseText;
alert(xhrResponse); // "[{\"model\": \"workoutcal.liftactivity\", \"pk\": 1, \"fields\": {\"name\": \"benchpress\"}}]"
alert(typeof xhrResponse); // string
var dbMatches = JSON.parse(xhrResponse);
alert(typeof dbMatches); // string! This is what I don't understand.
for(var i = 0; i < dbMatches.length; i++){
var link = document.createElement("a");
link.innerHTML = dbMatches[i]["name"];
link.onclick = function(){
var textbox = link.parentNode.parentNode.getElementsByTagName('input')[0];
textbox.value = link.innerHTML;
xhr.dropdown.innerHTML = "";
};
xhr.dropdown.appendChild(link);
}
} else {
document.getElementById("xhrPar").innerHTML = "Request was unsuccessful: "+xhr.status;
}
}
};
var url = "http://localhost:8000/workoutcal/";
if (this.name == "lift_string"){
url += "get_lifts";
} else if (this.name == "cardio_string"){
url += "get_cardio";
}
url = addURLParam(url, this.name, this.value);
xhr.open("get", url, false);
xhr.send(null);
}
Why isn't the string parsed into a Javascript object?

JSON.parse() returns literal which can be of type Object, String or other types depending upon the parameter being passed to the parse function. Consider the below expression which will return val of type string.
var val = JSON.parse(JSON.stringify("Hello"));

Related

Json parser and loop scheme

How can I loop my json file using my script, eg: I should choose whether to loop Schema A or Schema B.
My json file is:
{
"A":[
{
"id":"1",
"title":"Primo"
},
{
"id":"2",
"title":"Secondo"
}
],
"B":[
{
"id":"1",
"title":"Primo"
},
{
"id":"2",
"title":"Secondo"
}
]
}
Maybe setting a variable so as to define the scheme I have to display
My javascript file is:
var xmlhttp = new XMLHttpRequest();
var url = "myTutorials.txt";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
myFunction(myArr);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(arr) {
var out = "";
var i;
for(i = 0; i < arr.length; i++) {
out += arr[i].id + ' - ' + arr[i].title + '<br>';
}
document.getElementById("id01").innerHTML = out;
}
var xmlhttp = new XMLHttpRequest();
var url = "myTutorials.txt";
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var obj= JSON.parse(this.responseText);
myFunction(obj, 'A');
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(obj, key) {
var arr = obj[key];
var out = "";
var i;
for(i = 0; i < arr.length; i++) {
out += arr[i].id + ' - ' + arr[i].title + '<br>';
}
document.getElementById("id01").innerHTML = out;
}
Assuming that what you presented as JSON file is a response form network and is passed to myFunction, then why not to do something like:
let myRootArray;
if(/* some confitions */) {
myRootArray = myArr.A
} else {
myRootArray = myArr.B
}
myFunction(myRootArray );
Beside that, your names are a bit confusing, var myArr = JSON.parse(this.responseText);, while JSON.parse will return object, not an array.

Highlight substring in string with javascript

I have a input for searching in my website and I assign onkeyup event for that.
For example my string is : 'hello world' and when the user types 'llo'(or anything else)show the matched characters as highlighted with the other characters in search list below input.(like google search)
I try this but my code works for the first character not the all characters of string
My code :
//html
<input type="text" onKeyUp="search_customer(this)">
<div class="data_list"></div>
//javascript
function search_customer(input){
var text = input.value;
if(text == ''){
input.nextElementSibling.style.display = 'none';
return;
}
var xhr = new XMLHttpRequest();
xhr.onload = function(){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
var result = JSON.parse(xhr.responseText);
show_results(result , input);
}else{
alert('request was unsuccessful : ' + xhr.status);
}
}
xhr.open('post' , "<?php echo base_url('deal/search/')?>" , true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('text_search=' + text);
}
function show_results(res , input){
var datalist = input.nextElementSibling;
datalist.style.display = 'block';
if(res.length == 0){
datalist.innerHTML = '<div>nothing matched!<div>';
}else{
var div = document.createElement('div');
for(var i = 0 ; i < res.length ; i++){
if(res[i].full_name.substr(0 , input.value.length) == input.value){
var str = '<strong>'+res[i].full_name.substr(0 , input.value.length)+'</strong>' + res[i].full_name.substr(input.value.length);
var p = div.appendChild(document.createElement('p'));
p.innerHTML = str;
}
}
datalist.replaceChild(div , datalist.firstChild);
}
xhr.open;
}
You can use indexOf to get first index in the matched string and then calculate the last index. Also it's better to use the method slice to be able to use a negative index.
function search_customer(input){
var text = input.value;
if(text == ''){
input.nextElementSibling.style.display = 'none';
return;
}
var xhr = new XMLHttpRequest();
xhr.onload = function(){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
var result = JSON.parse(xhr.responseText);
show_results(result , input);
}else{
alert('request was unsuccessful : ' + xhr.status);
}
}
xhr.open('post' , "<?php echo base_url('deal/search/')?>" , true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('text_search=' + text);
}
function show_results(res , input){
var datalist = input.nextElementSibling;
datalist.style.display = 'block';
if(res.length == 0){
datalist.innerHTML = '<div>nothing matched!<div>';
}else{
var div = document.createElement('div');
for(let i = 0 ; i < res.length ; i++){
let search = input.value;
let match;
let lastIndx = (res[i].full_name.length-1) - res[i].full_name.indexOf(search) - (search.length-1);
if(lastIndx == 0){
match = res[i].full_name.slice(res[i].full_name.indexOf(search), res[i].full_name.length);
}else{
match = res[i].full_name.slice(res[i].full_name.indexOf(search), -lastIndx);
}
let str = res[i].full_name.slice(0, res[i].full_name.indexOf(search) ) + '<strong>' + match + '</strong>'+ res[i].full_name.slice(res[i].full_name.length-lastIndx, res[i].full_name.length);
let p = div.appendChild(document.createElement('p'));
p.innerHTML = str;
}
datalist.replaceChild(div , datalist.firstChild);
}
xhr.open;
}

JSON request - why is no picture displaying?

This code is meant to send a JSON request and store it under the variable json. It is then meant to display a picture depending on the value of a key (specifically if the key gender = male). No picture is displaying and I can't find a solution anywhere so is anyone able to help?
var i=20
while (i<10)
{var json = new XMLHttpRequest();
json.open('GET', "http://localhost:8081/getPersons?format=json", true);
json.send();
json.onreadystatechange = processRequest;
function processRequest(e) {
if (json.readyState == 4 && json.status == 200) {
var response = JSON.parse(json.responseText);
alert(response.ip);
}
}
var wantedKey = 'gender'; // your key here
var wantedVal = 'male'; // your value here
for(var i = 0; i < json.length; i++){
if(json[i].hasOwnProperty(gender) && json[i][gender] === male) {
document.createElement("img");
img.src = "http://advertdemo.ga/adverts/emotion_neutral/male/young/iphone.jpg";
img.width = "300px";
img.height = "300px";
// This next line will just add it to the <body> tag
document.body.appendChild(img);
break;
}
}}
There are a multitude of problems with your code, most importantly that you seem to misunderstand how AJAX works. Here's my fix with comments on what was wrong and where.
var json = new XMLHttpRequest();
json.open('GET', "http://localhost:8081/getPersons?format=json", true);
json.send();
// It's better to declare event handlers this way,
// your version relied on variable hoisting (look it up),
// which is not usually recommended.
json.onreadystatechange = function(e) {
if (json.readyState == 4 && json.status == 200) {
var response = JSON.parse(json.responseText);
// This was the main problem:
// Processing the result of the XHR should be *inside* the
// readystate (or load) event handler
for (var i = 0; i < response.length; i++) {
// You forgot to put the property name "gender" in quotes
// as well as the value "male"
// Also, the double check was unnecessary. This is perfectly safe.
if(response[i]['gender'] === 'male') {
var img = document.createElement("img");
img.src = "http://advertdemo.ga/adverts/emotion_neutral/male/young/iphone.jpg";
// You should set dimensions on the style property,
// not img directly
img.style.width = "300px";
img.style.height = "300px";
document.body.appendChild(img);
break;
}
}
}
}
try this:
var i=20
while (i<10)
{var json = new XMLHttpRequest();
json.open('GET', "http://localhost:8081/getPersons?format=json", true);
json.send();
json.onreadystatechange = processRequest;
function processRequest(e) {
if (json.readyState == 4 && json.status == 200) {
var response = JSON.parse(json.responseText);
alert(response.ip);
}
}
var wantedKey = 'gender'; // your key here
var wantedVal = 'male'; // your value here
for(var j = 0; j < json.length; j++){
if(json[i].hasOwnProperty(gender) && json[i][gender] === male) {
img= document.createElement("img");
img.setAttribute("src", "http://advertdemo.ga/adverts/emotion_neutral/male/young/iphone.jpg");
img.setAttribute("width", "300");
img.setAttribute("height", "300");
// This next line will just add it to the <body> tag
document.body.appendChild(img);
break;
}
}}

JS search returned xhr.responseText for div then remove div

I would like to search a xhr.responseText for a div with an id like "something" and then remove all the content from the xhr.responseText contained within that div.
Here is my xhr code:
function getSource(source) {
var url = source[0];
var date = source[1];
/****DEALS WITH CORS****/
var cors_api_host = 'cors-anywhere.herokuapp.com';
var cors_api_url = 'https://' + cors_api_host + '/';
var slice = [].slice;
var origin = self.location.protocol + '//' + self.location.host;
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function () {
var args = slice.call(arguments);
var targetOrigin = /^https?:\/\/([^\/]+)/i.exec(args[1]);
if (targetOrigin && targetOrigin[0].toLowerCase() !== origin &&
targetOrigin[1] !== cors_api_host) {
args[1] = cors_api_url + args[1];
}
return open.apply(this, args);
};
/****END DEALS WITH CORS****/
var xhr = new XMLHttpRequest();
xhr.open("GET", cors_api_url+url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = xhr.responseText;
var respWithoutDiv = removeErroneousData(resp);
}
else{
return "Failed to remove data.";
}
}
xhr.send();
}
remove div here:
/*This must be in JS not JQUERY, its in a web worker*/
function removeErroneousData(resp) {
var removedDivResp = "";
/*pseudo code for removing div*/
if (resp.contains(div with id disclosures){
removedDivResp = resp.removeData(div, 'disclosures');
}
return removedDivResp;
}
You can dump the response in a div and then search for that div you want empty its content.
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = xhr.responseText;
$('div').attr('id', 'resp').html(resp);
$('#resp').find('disclosures').html('');
//var respWithoutDiv = removeErroneousData(resp);
}
else{
return "Failed to remove data.";
}
}

Request.Params.AllKeys[0] sometimes null

I have a strange problem, randomly my webmethod will return null values for Request.Params.AllKeys[0], if I refresh the page and attempt it again it will work.
Basically what I'm doing is I have a canvas that I submit to a webmethod like this:
function convertCanvas(strType) {
if (strType == "PNG") {
if (ValidateForm('form1')) {
//var oImg = Canvas2Image.saveAsPNG(canvas, true);
//var canvasData = canvas.toDataURL("image/png");
var canvasData = document.getElementById("panel").toDataURL("image/png");
var xhr = new XMLHttpRequest();
xhr.open("POST", "/Job/SignatureSave", true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader("Content-length", canvasData.length);
xhr.setRequestHeader("X-File-Name", "<%: Model.RequestMV.RequestID %>");
// subscribe to this event before you send your request.
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
//alert the user that a response now exists in the responseText property.
if (xhr.responseText == 'yes') {
window.location.reload(true);
//OnSubmitForm();
}
else {
alert('Saving signature failed, please try again');
}
// And to view in firebug
console.log('xhr', xhr.responseText)
console.log('data:', canvasData)
}
}
xhr.send(canvasData);
}
}
}
I know that canvasData does contain data even when it alerts to show that signature did not save as I have canvasData in an alert on each post and there is always data even when the webmethod returns failure.
My webmethod is like this:
[WebMethod]
public string SignatureSave(string data)
{
try
{
var b = Request.Params.AllKeys[0];
var filename = Request.Headers["X-File-Name"];
string imageAsBase64 = b.ToString();
string fileName = filename.ToString();
imageAsBase64 = imageAsBase64.Replace("data:image/png;base64,", "");
imageAsBase64 = imageAsBase64.Replace(" ", "+");
int remainder = imageAsBase64.Length % 4;
for (int i = 4; i > remainder; i--)
{
imageAsBase64 = imageAsBase64 + "=";
}
string imagestring = imageAsBase64;
byte[] imageAsBytes = Convert.FromBase64String(imagestring);
var saveToFileLoc = Path.Combine(#"" + WebConfigurationManager.AppSettings["SignaturePath"].ToString(), fileName + ".png");
// save the file.
var fileStream = new FileStream(saveToFileLoc, FileMode.Create, FileAccess.ReadWrite);
fileStream.Write(imageAsBytes, 0, imageAsBytes.Length);
fileStream.Close();
return "yes";
}
catch (Exception e)
{
return "no";
}
}
Why on the javascript side is the data there and being sent in the request, but on the codebehind side it sometimes, not all the times, only sometimes says the first element of params is null?

Categories