JSON file not loading properly [duplicate] - javascript

This question already has answers here:
Get JSON data from external URL and display it in a div as plain text
(7 answers)
How to get the response of XMLHttpRequest?
(4 answers)
Closed 7 years ago.
I want to read this JSON file, but the xmlhttp is returning empty.
This is the getJson() function that I am using. I am running this from my local machine.
var getJSON = function(dir) {
console.log(dir);
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
console.log(xmlhttp);
}
xmlhttp.open("GET", dir, true);
xmlhttp.send();
};

Alberto,
Since you are using xmlHttp asynchronously, and assuming you want to save the response in a variable, you'll have to modify your getJSON function to accept a callback function and pass the result and/or an error to the callback. So getJSON should be something like this:
var getJSON = function(dir, callback) {
console.log(dir);
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
if (xmlhttp.status == 200) {
console.log('request finished', xmlhttp);
// pass the response to the callback function
callback(null, xmlhttp.responseText);
} else {
// pass the error to the callback function
callback(xmlhttp.statusText);
}
}
}
xmlhttp.open("GET", dir, true);
xmlhttp.send();
}
To use the function, you'll want something like this:
var myReturnedJSON;
getJSON("http://gomashup.com/json.php?fds=geo/usa/zipcode/state/AL&jsoncallback=", function(error, data){
if(error) {
//handle the error
} else {
//no error, parse the data
myReturnedJSON = JSON.parse(data)
}
});
Now, the issue with this is that the source returns invalid JSON:
({
"result":[
{
"Longitude" : "-086.466833",
"Zipcode" : "35004",
"ZipClass" : "STANDARD",
"County" : "SAINT CLAIR",
"City" : "MOODY",
"State" : "AL",
"Latitude" : "+33.603543"
}
]}
)
For this to be valid, it should look like:
{
"result":[
{
"Longitude" : "-086.466833",
"Zipcode" : "35004",
"ZipClass" : "STANDARD",
"County" : "SAINT CLAIR",
"City" : "MOODY",
"State" : "AL",
"Latitude" : "+33.603543"
}
]}
The difference is in that the valid JSON is not wrapped in parentheses.
So, let's modify the callback function to strip out the first and last characters of the response:
function(error, data){
if(error) {
//handle the error
} else {
//no error, parse the data
myReturnedJSON = JSON.parse( data.substr(1, data.length - 2) );
}
}
I hope that helps!
- Oscar

Related

How to fetch data from XMLHttpRequest to GridView QML

I am trying to show movies in a grid with 5 movies per row. I use a predefined movie list. I successfully fetched data from https://api.themoviedb.org/4/list/1.
Here is my code:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 1920
height: 1080
visible: true
title: qsTr("Hello World")
Component.onCompleted: {
mojgrid.focus = true
}
function dobioResponseNapraviModel(response) {
console.log("dobioResponseNapraviModel", typeof response)
mojgrid.model=response
}
function request(){
console.log("BOK")
const xhr=new XMLHttpRequest()
const method="GET";
const url="http://api.themoviedb.org/4/list/1";
xhr.open(method, url, true);
xhr.setRequestHeader( "Authorization", 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI5YjBkOGVlMGQzODdiNjdhYTY0ZjAzZDllODM5MmViMyIsInN1YiI6IjU2MjlmNDBlYzNhMzY4MWI1ZTAwMTkxMyIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.UxgW0dUhS62m41KjqEf35RWfpw4ghCbnSmSq4bsB32o');
xhr.onreadystatechange=function(){
if(xhr.readyState===XMLHttpRequest.DONE){
var status=xhr.status;
if(status===0 || (status>=200 && status<400)){
//the request has been completed successfully
// console.log(xhr.responseText.results)
dobioResponseNapraviModel(JSON.parse(xhr.responseText).results)
}else{
console.log("There has been an error with the request", status, JSON.stringify(xhr.responseText))
}
}
}
xhr.send();
}
/* function request(url, callback) {
var xhr=new XMLHttpRequest();
xhr.open("GET", url, true)
xhr.onreadystatechange = function() {
if(xhr.readyState===4) {
callback(xhr.responseText)
}
}
xhr.open("GET", url)
xhr.setRequestHeader( "Authorization", 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI5YjBkOGVlMGQzODdiNjdhYTY0ZjAzZDllODM5MmViMyIsInN1YiI6IjU2MjlmNDBlYzNhMzY4MWI1ZTAwMTkxMyIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.UxgW0dUhS62m41KjqEf35RWfpw4ghCbnSmSq4bsB32o');
xhr.send()
}*/
GridView {
id:mojgrid
anchors.fill: parent
Keys.onUpPressed: {
request()
}
delegate: Rectangle{ id: rect; width:500;height: 400; color:'gray'
Image{ anchors.fill:parent
fillMode: Image.PreserveAspectFit
source:modelData.backdrop_path
}
Text{ text:modelData.original_title}
}
}
}
Here are the properties I need to show in GridView when I run the application:
But I get message that the image cannot be opened:
Does anybody have any idea what is wrong? Any help would be appreciated, thank you.
What you're missing is a model to store the data in. You are incorrectly trying to bind the GridView's model to a function. Instead, create an empty ListModel, and then when your request is complete, populate that model. The GridView will then update automatically when the model updates.
ListModel {
id: movieModel
}
GridView {
...
model: movieModel
}
Component.onCompleted: {
request()
}
function request() {
...
xhr.onreadystatechange=function(){
if(xhr.readyState===XMLHttpRequest.DONE){
var status=xhr.status;
if(status===0 || (status>=200 && status<400)){
// Parse response data and append it to your model
for (var i = 0; ...) {
movieModel.append( {...} )
}
}
}
}
}
UPDATE:
You've changed your question now. The reason you can't open those images is because you are not using the full path of the url. Your http request is apparently returning relative paths. So just prepend the base url to the image name.
source: "http://api.themoviedb.org/4/list/1" + modelData.backdrop_path

JSON post request shows 405 not allowed error (using XMLHttpRequest())

here's my js code:
var myreq=new XMLHttpRequest();
myreq.open("GET","https://<username>.github.io/test/data/data.json",true);
myreq.onload =function(){
console.log(JSON.parse(myreq.response));
}
myreq.send();
const data={
"name": "jayant",
"job": "leader"
};
function here()
{
var myreq1=new XMLHttpRequest();
myreq1.onload = () => {
// print JSON response
if (myreq1.status >= 200 && myreq1.status < 300) {
// parse JSON
const response = JSON.parse(myreq1.responseText);
console.log(response);
}
};
myreq1.open("POST",'https://<username>.github.io/test/data/data.json');
myreq1.setRequestHeader('Content-Type', 'application/json');
myreq1.send(JSON.stringify(data));
}
Function here is called on a button click
and here's my JSON code:
[
{
"name1":"jayant",
"age":58,
"pass":"LetsLearnJson"
},
{
"name1":"jayant2",
"age":45,
"pass":"ok"
},
{
"name1":"jayant3",
"age":24,
"pass":"test"
},
{
"name1":"abcd",
"age":75,
"pass":"abcd"
}
]
I am getting this error when I try to post:
POST https://<username>.github.io/test/%22https://<username>.github.io/test/data/data.json%22 405
Please help. I have tried many things already available online but nothing seems to work
The 405 Method Not Allowed Error occurs when the web server is configured so that you cannot perform a specific action for a specific URL. It is an HTTP response status code that indicates that the request method is known to the server, but is not supported by the target resource.

Querying Google Place API for a dialogflow response

I am trying to query Google Place API for details in order to display a map (by obtaining first coordinates) and location information (address) as a chatbot response. I have written this quote, but I am have having problems with the Google Place API response. Appreciate any help available.
var path1 = `/maps/api/place/details/json?placeid=${placeID}&fields=name,formatted_address,geometry&key=${googleAPI}`;
details = getPlace(path1);
console.log('details: ' + details); //debug statement
function getPlace (path1) {
const host = 'https://maps.googleapis.com';
var url = host + path1;
var data = null;
return new Promise(function(resolve, reject) {
request (url, function (err,response,body) {
if(!err){
try{
data = JSON.parse(body);
resolve(data);
}catch (err) {
console.error('parsing error');
reject('Error during parsing of data: ' + err.message);
}
} else {
console.error('request error');
reject('Unable to get data. Statuscode: ' + response.statusCode);
}
});
});
}
The response I am getting from Firebase is :
dialogflowFirebaseFulfillment details: [object Promise]
when I try the URL in browser, I am getting a proper response
https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJJ0JHF9A3zDERwazNPMoMKAg&fields=name,formatted_address,geometry&key=API-Key
{
"html_attributions" : [],
"result" : {
"formatted_address" : "Level 1, Smart Banking Area Menara Citibank, 165, Jalan Ampang, Kuala Lumpur, 50450 Kuala Lumpur, Wilayah Persekutuan Kuala Lumpur, Malaysia",
"geometry" : {
"location" : {
"lat" : 3.1600754,
"lng" : 101.717633
},
"viewport" : {
"northeast" : {
"lat" : 3.161558980291502,
"lng" : 101.7188249302915
},
"southwest" : {
"lat" : 3.158861019708498,
"lng" : 101.7161269697085
}
}
},
"name" : "Citibank Malaysia - Kuala Lumpur"
},
"status" : "OK"
}
Not sure what is the problem here, anyone able to help?
It may be because you are not awaiting the Promise in getPlace() to resolve before continuing with your code.
Try making the function you are calling getPlace() from async and using await when calling the function. For example:
async function parentFunction() {
var path1 = `/maps/api/place/details/json?placeid=${placeID}&fields=name,formatted_address,geometry&key=${googleAPI}`;
details = await getPlace(path1);
console.log('details: ' + details);
}
Here's a good post that explains async code and how to deal with it

How to format data for XDomainRequest

I need to post data to a cross origin web service using json. This works perfectly in ie10+ but not in ie8/9.
After researching i discovered i need to use XDomainRequest but am unsure how to format the data.
For example, can i just wrap a string around my JSON object and send it or does it need to be in name value pairs like?
Im currently sending
{
"field": {
"field": "blah",
"field": "blah",
"field": "blah",
"field": "blah",
"field": [
"ML08BWV",
"MJ08OJF",
"MJ10PYO",
"FT10EXZ",
"SH57XUM"
]}
}
I'm definitely hitting the server but the server logs suggest that im not sending any data in the request payload. :/
Edit: Javascript Code
var xdr = new XDomainRequest(); // Use Microsoft XDR
xdr.open('POST', URL);
xdr.onload = function () {
//xdr.contentType = "application/json";
var dom = new ActiveXObject('Microsoft.XMLDOM'), JSON = $.parseJSON(xdr.responseText);
dom.async = false;
if (JSON == null || typeof (JSON) == 'undefined') {
JSON = $.parseJSON(data.firstChild.textContent);
}
//Do something with json
};
xdr.onerror = function () {
_result = false;
};
xdr.ontimeout = function () {
alert('xdr ontimeout');
};
xdr.onprogress = function () {
alert("XDR onprogress");
alert("Got: " + xdr.responseText);
};
xdr.send("json=" + dataToSend);
dataToSend is in the json format as posted above

JSON parsing issues are giving me a 'Cannot read property of undefined' error.

I'm working on cloud code that pings eBay, returns JSON, parses it, and stores the top two categories into an array. The parameters sent to eBay are based on what a user types into itemSearch bar the iOS app. When I attempt to send a query like "iPhone", it gives this error:
TypeError: Cannot read property 'findItemsByKeywordsResponse' of undefined
at Object.Parse.Cloud.httpRequest.success (main.js:37:15)
at Object.<anonymous> (<anonymous>:565:19) (Code: 141, Version: 1.2.18)
Here is my objective-c code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.nextButton) return;
if (self.itemSearch.text.length > 0) {
[PFCloud callFunctionInBackground:#"eBayCategorySearch"
withParameters:#{#"item": self.itemSearch.text}
block:^(NSString *result, NSError *error) {
if (!error) {
NSLog(#"Successfully pinged eBay!");
}
}];
}
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
The cloud code (main.js) running on Parse:
Parse.Cloud.define("eBayCategorySearch", function(request, response) {
url = 'http://svcs.ebay.com/services/search/FindingService/v1';
Parse.Cloud.httpRequest({
url: url,
params: {
'OPERATION-NAME' : 'findItemsByKeywords',
'SERVICE-VERSION' : '1.12.0',
'SECURITY-APPNAME' : '*APP ID GOES HERE*',
'GLOBAL-ID' : 'EBAY-US',
'RESPONSE-DATA-FORMAT' : 'JSON',
'itemFilter(0).name=ListingType' : 'itemFilter(0).value=FixedPrice',
'keywords' : request.params.item,
// your other params
},
success: function (httpResponse) {
var response = JSON.parse(httpResponse.text)
// count number of times each unique primaryCategory shows up (based on categoryId), return top two (done with a for loop?)
var userCategories = {};
var data = httpResponse.data
data.findItemsByKeywordsResponse.searchResult[0].item.forEach(function(item)
{
var id = item.primaryCategory[0].categoryId;
if (userCategories[id]) userCategories[id]++;
else userCategories[id] = 1;
});
var top2 = Object.keys(userCategories).sort(function(a, b)
{return userCategories[b]-userCategories[a]; }).slice(0, 2);
console.log('Top two categories: ' + top2.join(', '));
response.success(httpResponse.data)
// if user has criteria info for one of the categories already, default to that, send to matchcenter
// if user has criteria for both categories, ask which one, default to selected categories criteria, send to matchcenter
// if user has no criteria for either category, redirect to criteriaViewController, save the criteria user inputs, send to matchcenter
// deal with success and respond to query
},
error: function (httpResponse) {
console.log('error!!!');
console.error('Request failed with response code ' + httpResponse.status);
}
});
});
The JSON usually looks like this when returned:
{
"findItemsByKeywordsResponse":[
{
"ack":[
"Success"
],
"version":[
"1.12.0"
],
"timestamp":[
"2014-03-26T18:29:40.583Z"
],
"searchResult":[
{
"#count":"100",
"item":[
{
"itemId":[
"151258132867"
],
"title":[
"Apple iPhone 4 - clean esn - Black (Verizon) Smartphone"
],
"globalId":[
"EBAY-US"
],
"primaryCategory":[
{
"categoryId":[
"9355"
],
"categoryName":[
"Cell Phones & Smartphones"
I don't think it's being returned properly, hence its inability to find "findItemsByKeywordsResponse". Is there a way I can print out the JSON being returned, to see whether I'm parsing the wrong thing?
You are parsing your response:
var response = JSON.parse(httpResponse.text)
But after that you don't use it. You work instead with httpResponse.data.
So try using your response object:
response.findItemsByKeywordsResponse.searchResult[0]......

Categories

Resources