React JS: Unexpected token < in JSON at position 0 - javascript

I'm trying to parse and get fetch data from URL, but got the error like:
Unexpected token < in JSON at position 0
the URL contains this such of data:
<wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:kict="kict" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.0.70:28080/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd kict http://192.168.0.70:28080/geoserver/wfs?service=WFS&version=1.0.0&request=DescribeFeatureType&typeName=kict%3Av_plans_photo">
<gml:boundedBy>
<gml:null>unknown</gml:null>
</gml:boundedBy>
<gml:featureMember>
<kict:v_plans_photo fid="v_plans_photo.fid-400b9b06_17e425c6260_-1a99">
<kict:rownum>61689</kict:rownum>
<kict:plan_id>6178a7a0974e58001ac90ac5</kict:plan_id>
<kict:cmo>5c38212c23b65b0d045d2de8</kict:cmo>
<kict:cmo_str>5c38212c23b65b0d045d2de8</kict:cmo_str>
<kict:plan_name/>
<kict:plan_cn>포트홀 작업추가</kict:plan_cn>
<kict:opert_ty>B1</kict:opert_ty>
<kict:operTy>B1</kict:operTy>
<kict:opert_sttus>A4</kict:opert_sttus>
<kict:opert_plan_cn>포트홀 작업추가</kict:opert_plan_cn>
<kict:create_at_year>2021</kict:create_at_year>
<kict:create_at_month>10</kict:create_at_month>
<kict:create_at_week>43.0</kict:create_at_week>
<kict:created_at>2021-10-27T01:13:04.557Z</kict:created_at>
<kict:created_by>강릉_보수원002</kict:created_by>
<kict:cvpl_ty>5cfda3bab615b60845c79dda</kict:cvpl_ty>
<kict:acmslts_id>6178a89e974e58001ac90b02</kict:acmslts_id>
<kict:cvpl_ty_code>900900</kict:cvpl_ty_code>
<kict:cvpl_ty_nm>포트홀</kict:cvpl_ty_nm>
<kict:cvpl_name>포트홀</kict:cvpl_name>
<kict:cmo_org_code>1613208</kict:cmo_org_code>
<kict:cmo_grp_nm>원주청</kict:cmo_grp_nm>
<kict:cmo_code>22</kict:cmo_code>
<kict:cmo_nm>강릉국토관리사무소</kict:cmo_nm>
<kict:cmoNm>강릉국토관리사무소</kict:cmoNm>
<kict:photo_type>완료</kict:photo_type>
<kict:begin_lat>37.7164584026444</kict:begin_lat>
<kict:begin_lon>128.987696737366</kict:begin_lon>
<kict:photo_lat>37.7161098</kict:photo_lat>
<kict:photo_lon>128.9880585</kict:photo_lon>
<kict:geom>
<gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">128.9880585,37.7161098</gml:coordinates>
</gml:Point>
</kict:geom>
<kict:photo_url>http://hms.molit.go.kr:9080/api/uploads/2021/6178a7a0974e58001ac90ac5_202110271017147661635297434478.png</kict:photo_url>
<kict:store_path>uploads/2021/6178a7a0974e58001ac90ac5_202110271017147661635297434478.png</kict:store_path>
<kict:photo_filename>6178a7a0974e58001ac90ac5_202110271017147661635297434478.png</kict:photo_filename>
<kict:photo_size>1122621</kict:photo_size>
</kict:v_plans_photo>
</gml:featureMember>
</wfs:FeatureCollection>
I just used fetch to parse and fetch data like below:
let url = "/geoserver/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=kict:v_plans_photo&srsName=EPSG:4326&maxFeatures=10000&format_options=callback:getJson&cql_filter=INTERSECTS(geom, POINT (128.9880585 37.7161098))"
if (url) {
fetch(url, {
headers : {
'Accept': 'application/json'
}
})
.then(response => response.json())
.then((response) => {
console.log(response)
},
(error) => {
this.setState({
isLoaded: true,
error
});
console.log(`fetch failed: ${this.state.error}`)
}
)
}
How can I get data from that URL using fetch?

It is throwing such error because you are trying to parse a non-json datatype.
Response data is actually an XML. You have to first parse the text and then parse the XML.
Refer this - https://codetogo.io/how-to-fetch-xml-in-javascript/

Visit this page for detailed info
The json() method of the Response interface takes a Response stream and reads it to completion. It returns a promise which resolves with the result of parsing the body text as JSON.
Note that despite the method being named json(), the result is not JSON but is instead the result of taking JSON as input and parsing it to produce a JavaScript object.
As you can see, the json() takes JSON format as input and then parses it, as your data is not in a JSON format you are bound to get the following error
Unexpected token < in JSON at position 0
Your result is in XML format. Try the following
let url = "/geoserver/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=kict:v_plans_photo&srsName=EPSG:4326&maxFeatures=10000&format_options=callback:getJson&cql_filter=INTERSECTS(geom, POINT (128.9880585 37.7161098))"
if (url) {
fetch(url, {
headers : {
'Accept': 'application/json'
}
})
.then(response => response.text())
.then(response => {
const parser = new DOMParser();
const xml = parser.parseFromString(data, "application/xml");
console.log(xml);
},
(error) => {
this.setState({
isLoaded: true,
error
});
console.log(`fetch failed: ${this.state.error}`)
}
)
}

Related

Accessing response in case of Error when using fetch API

I am using following fetchProtectedResource call to a REST Service:
return this.fetcher.fetchProtectedResource(url, {
method: 'PUT',
body: body
}, config)
.toPromise()
.then(response => response.json()
)
.catch(e => {
//How to get json from e object????
return null;
});
I can see in Browser that in case of error, the server return json in response but I cant find any documentation about the structure of this error Object to get this JSON.

Can't use response.json() on received user object from MS Graph

I'm trying to get a user from the MS Graph API.
export const getUser = async (id) => {
//Gives me the token
const token = await getToken(["User.Read", "User.ReadWrite"])
//Appends to headers
const headers = getHeaders(token)
const options = {
method: "GET",
headers: headers
};
return fetch(`https://graph.microsoft.com/v1.0/users/${id}`, options)
}
getUser("MYID").then(response => response.json()).then(response => {
debugger
}).catch((error) => {
debugger
})
Normally I can use .json() to resolve promises from MS Graph, but this call fails with the following error:
Unexpected token < in JSON at position 0
If I remove .json() I can read the response, which gives me the following:
response: Response
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
Given the fact that the body object should be of type ReadableStream, my intuition tells me that I in fact should be able to resolve the promise with .json(), i.e. response.body.json(). However, when I try to do so, I get the following error:
TypeError: response.body.json is not a function at http://localhost:3000/static/js/main.chunk.js:4679:40
I'm pretty unsure what's going on, and naturally I would love if you guys could give me some insights on what's going on. All my other graph "GET" calls encounter no problem when I want to resolve the readableStream.
I believe you are getting response body as html or xml which is why .json() which is used to parse the data to json is throwing exception Unexpected token < in JSON at position 0

Request does not return complete response. Error JSON.parse

I have a problem in nodejs, I make a request to an api using https.request, the response contains an object of 10000 rows.
What happens is that the entire object does not arrive, and parsing gives the error: Unexpected end of JSON input;
Can someone help?
Function to request:
function request({
options,
method,
resource,
queryParams,
bodyParams,
}) {
return new Promise((resolve, reject) => {
const hasBodyParams = !!bodyParams;
const stringifyedQueryParams = strigifyQueryParams(queryParams);
const optionsRequest = {
...options,
method,
path: `${resource}${stringifyedQueryParams}`,
};
const req = https.request(optionsRequest, (res) => {
res.setEncoding(configs.ENCODING);
res.on(events.DATA, data => resolve({
body: JSON.parse(data),
statusCode: res.statusCode,
}));
});
req.on(events.ERROR, error => reject(error) );
hasBodyParams && req.write(bodyParams);
req.end();
});
}
As I suspected in the comments, you're not handling multiple data-events.
When receiving large responses from a request, the data-event is called multiple times, each time with a chunk of data from the response (not the complete response).
When you're parsing a chunk, the complete JSON document hasn't been transmitted yet, so the parsing fails with the "Unexpected end of JSON stream" error
In short, you need to:
Create a variable to collect the complete body
On a data-event, append the new chunk to the complete body
When the end-event is called, parse the full body.
Here is a short example, adopted from the official documentation:
https.request(options, (res) => {
// PARTIAL example
res.setEncoding("utf8"); // makes sure that "chunk" is a string.
let fullBody = "";
res.on("data", data => {
fullBody += data;
});
res.on("end", () => {
const json = JSON.parse(fullBody);
// work with json
});
});

Fetch() API not updating JSON file

I have a JSON file I want to read from and write to that looks like this:
[
"test#example.com"
]
I want to add info to this file using the fetch() API. So far, I can only read from this file.
let handle = JSON.stringify(`test#example2.com`); // handle is fine irrelevant of "" or ``
const url = `../json/emails.json`; // URL is fine
const options = {
method: `POST`, // PUT return error at second fetch: SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: handle
};
fetch(url) // this fetch is fine
.then(response => {
if (!response.ok) {
throw new Error(`Error getting the stuff`);
}
return response;
})
.then(r => r.json())
.then(data => {
console.log(`Data: ` + data);
});
fetch(url, options)
.then(response => {
if (!response.ok) {
throw new Error(`Error getting the stuff`);
}
return response;
})
.then(a => a.json())
.then(append => {
console.log(`Data updated: ` + append);
}).catch(err => {
console.error('Request failed: ', err);
});
I get no errors (aside from that PUT comment); ESLint and TSLint don't have any problem with the JS file nor with the JSON file. What am I doing wrong?
fetch() is an API for making HTTP requests.
It can't write to files. In particular, nothing can write to arbitrary URLs. (Imagine if it was possible for any browser to write new data to http://www.google.com/!)
If you want your PUT or POST request to change data on your server, then you must write server-side code to process the request and edit the file.

Aurelia | json parse uncaughtable exception?

So i am trying to make this post request, following aurelia docs:
http://aurelia.io/hub.html#/doc/article/aurelia/fetch-client/latest/http-services/3
And this is the request:
httpClient.configure(config => {
config
.withBaseUrl(baseUrl)
});
this.client = httpClient;
this.client.fetch(`/api/Register/${userName}`, {
method: "post",
body: json(loginInformation),
headers: {
'Access-Control-Allow-Origin' : '*',
'Accept': 'application/json'
}
}) .then(response => this.safelyParseJSON(response))
.then(data => this.setup(data));
where safetyParseJSON is:
safelyParseJSON(response) {
var parsed
try {
parsed = response.json();
} catch (e) {
}
return parsed
}
but i keep receiving this error:
"uncaught (in promise) SyntaxError: Unexpected end of JSON input"
Anyone have any idea on what am i doing wrong?
Note:
I am receiving this error only when receiving 404 / 500 from the server, if the results are ok, this works.
Note2: that i am wrapping this function inside try-catch but this still doesn't work, it doesn't catch the exception.
Note3: I have tried to replace this line:
parsed = response.json();
with this line:
parsed = JSON.parse(response);
But than the response is always undefined.
check the response's status prior to calling .json():
.then(response => {
if (response.ok) {
return response.json().then(data => this.setup(data));
}
return Promise.reject(response.text());
});
I ended up using Jeremy Danyow answer, with a small change:
.then(response => {
if (response.ok && response.status === 200) {
return response.json().then(data => this.setup(data));
}
return Promise.reject(response.text());
});
adding the response.status check was necessary in my case as response.ok was true for status code 204 (No content) aswell.

Categories

Resources