Problem
I am using the Lichess API where it is stated under Get Export games of a user that the query parameter max
is of type integer and can be set >= 1
.
In the following snippet of code I am not able to fetch data with max
larger than 1, but it works for max=1
. It also does not work in this identical JSFiddle, nor in my VsCode project. They work only if I set the query max
to the value 1.
new Vue({
el: "#app",
data: {
temp: 1
},
methods: {
async fetchData() {
const response = await fetch(
`https://lichess.org/api/games/user/Thibault?max=2&rated=false`,
{headers:{
Accept:'application/x-ndjson'
}}
);
const data = await response.json();
console.log(data);
},
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="fetchData()"> fetch data</button>
</div>
Things I have tried
I have tried using async await
, and removing them but with no success, I have tried to search online for solutions and read the API documentation thoroughly but it just doesn't work.
the Network devtools says the content-type
is x-ndjson so I set application/x-ndjson
in my header
tag (solving another first problem I had before).
Does anyone know what is going on?
CodePudding user response:
Coming data format is nd-json and Lichess API offers a utility function to help reading NDJSON streamed responses.
If you use this, you will get the data:
new Vue({
el: "#app",
data: {
temp: 1
},
methods: {
async fetchData() {
const response = await fetch(
`https://lichess.org/api/games/user/Thibault?max=2&rated=false`,
{headers:{
Accept:'application/x-ndjson'
}}
).then(readStream(onMessage))
.then(onComplete);
console.log(arr);
},
}
})
const readStream = processLine => response => {
const stream = response.body.getReader();
const matcher = /\r?\n/;
const decoder = new TextDecoder();
let buf = '';
const loop = () =>
stream.read().then(({ done, value }) => {
if (done) {
if (buf.length > 0) processLine(JSON.parse(buf));
} else {
const chunk = decoder.decode(value, {
stream: true
});
buf = chunk;
const parts = buf.split(matcher);
buf = parts.pop();
for (const i of parts.filter(p => p)) processLine(JSON.parse(i));
return loop();
}
});
return loop();
}
const arr = [];
const onMessage = obj => arr.push(obj);
const onComplete = () => console.log('The stream has completed');