Reputation: 142
I have an app runs Rails in backend, Javascript frontend. My controllers, routes and CORS is fine. My Post and Get requests are working fine. However when I make a patch request, it successfully does patching but as response.text()
, I get empty string. So when I use response.json()
, it gives me Uncaught (in promise) SyntaxError: Unexpected end of JSON input at game.js:25 error.
I need to know the source of the problem.
static patchGame() {
const numberOfClicks = parseInt(document.getElementById('click-number').textContent, 10)
const score = parseInt(document.getElementById('score').textContent,10)
const gameID = document.getElementById('gameID').value
const gameObj = {game: {click_number: numberOfClicks, score: score}}
const options = {
method: "PATCH",
headers: {"Content-Type": "application/json",
"Accept": "application/json"},
body: JSON.stringify(gameObj)
}
fetch(`http://localhost:3000/games/${gameID}`, options).then(resp => {debugger}).then(game => { debugger }) // NEVER HITS last debugger
}
These are the resp debugger values I get,
>resp
<-Response {type: "cors", url: "http://localhost:3000/games/28", redirected: false, status: 204, ok: true, …}
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 204
statusText: "No Content"
type: "cors"
url: "http://localhost:3000/games/28"
__proto__: Response
>resp.text()
<-Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
>resp.json()
<-Promise {<rejected>: TypeError: Failed to execute 'json' on 'Response': body stream already read
at eval (eval at <a…}
__proto__: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: TypeError: Failed to execute 'json' on 'Response': body stream already read at eval (eval at <anonymous> (file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:1:1), <anonymous>:1:6) at file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:24:84
message: "Failed to execute 'json' on 'Response': body stream already read"
stack: "TypeError: Failed to execute 'json' on 'Response': body stream already read\n at eval (eval at <anonymous> (file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:1:1), <anonymous>:1:6)\n at file:///Users/muratogulcansahin/Desktop/DanceMemory/frontend/game.js:24:84"
__proto__: Error
>resp.body
<-ReadableStream {locked: true}
locked: true
__proto__: ReadableStream
Upvotes: 0
Views: 1767
Reputation: 844
NOTE: I had mis-read the question, and only went on debugger values instead of reading the question fully. This is the correct answer to the question: https://stackoverflow.com/a/67453072/1710359. I will leave this answer as-is in case someone else has this issue too.
ORIGINAL ANSWER:
The code that fails is not in the code that was provided.
This is caused by using .json()
multiple times, and is (I assume) located within that second .then()
call.
Please revise your code and make sure you only call .json()
one time per request, as .json()
consumes the resulting body.
You are able to monitor if the body has been consumed by using the .bodyUsed
variable, which is available in any fetch
response.
This is an explanation based on your own debugger logs:
>resp
<-Response {type: "cors", url: "http://localhost:3000/games/28", redirected:
// prints your server's response data (resp.bodyUsed is now *false*)
>resp.text()
<-Promise {<pending>}
// prints your server's response data as *text*, and *consumes* the body (resp.bodyUsed is now *true*)
>resp.json()
<-Promise {<rejected>: TypeError: Failed to execute 'json' on 'Response': body
// fails to print your server's response data, because you have *already* consumed the body by using `.text()`
Upvotes: 1
Reputation: 439
it looks like there is a 204
response, which is what I'd expect from a successful PATCH
, meaning no content is being returned from the server. That would certainly explain the issues you are having with this.
Basically, I won't expect to be able to call .text()
or more specifically .json()
on the absent content.
Ideally, PUT
and PATCH
requests are not expected to return data. 200
s are acceptable but 204
s are the most appropriate in my honest opinion
Upvotes: 3