So im very new to fullstack and been working on a little vanilla js project to make a website that calls a server I run that calls chess.com api, for example retrieving all elo ratings is:
So I made a backend call in node-js:
const fetch = require('node-fetch');
exports.getChessManStats = () => {
return (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
const username = req.param('username');
console.log(req.param('username'));
fetch(`https://api.chess.com/pub/player/${username}/stats`)
.then(res2 => res2.json() )
.then(chessManData => {
res.json({
daily: chessManData.chess_daily.last.rating,
rapid: chessManData.chess_rapid.last.rating,
blitz: chessManData.chess_blitz.last.rating,
bullet: chessManData.chess_bullet.last.rating,
})
})
.catch(err => console.log(err));
}
};
the code then runs with express on the main.js with:
const app = express();
app.get('/getRating',chessManController.getChessManStats());
obviously later down the line I called app.listen(3000)
.
So then at the frontend I made a button that calls this function :
const makeUserStats = () => {
const username = document.getElementById('username').value;//id=username is type input
document.getElementById('rating').innerHTML = `Searching`; //making the rating div into 'searching'
console.log(`http://localhost:3000/getRating?username=${username}`)//just seeing the sting I send
fetch(`http://localhost:3000/getRating?username=${username}`)
.then(rating => {
document.getElementsByClassName('statButton').disabled = true;//disabling buttons until the data arrives
console.log('got json');
return rating.json();
})
.catch(err => console.log(err))//looking for errors
.then((userRating => {
window.userRating = userRating;//saving the stats globaly to use in other buttons
window.user = username;
}))
.then(() => {
document.getElementsByClassName('statButton').disabled = false;//enabling the buttons again
document.getElementById('rating').innerHTML = `${window.user} rating is:`;
})
}
and now when I press the button it works with some usernames and with some dont. YoniRamot (mine) works, hikaru (pro player) works, atomicstew (friend) doesnt work, idobl (friend) doesnt work. and the wierd part is it does'nt catch any errors, just waiting for answer that it never gets. but if you go the the api they all exist:
https://api.chess.com/pub/player/hikaru/stats --proplayer
the console of the backend shows:
atomicstew
TypeError: Cannot read property 'last' of undefined
at C:\Users\Yonatan\Desktop\coding\training\intermediateChess\backend\controllers\chessStats.js:12:45
at processTicksAndRejections (internal/process/task_queues.js:93:5)
meaning that the backend gets the username but does'nt find it in the api for some reason.
please help my mind is blowing at this point.
-edit 1-
So I added a console log before sending the res with the data, and it printed:
atomicstew
{
chess_rapid: {
last: { rating: 1228, date: 1612114999, rd: 28 },
best: {
rating: 1265,
date: 1611786478,
game: 'https://www.chess.com/live/game/6380128206'
},
record: { win: 233, loss: 202, draw: 19 }
},
chess_blitz: {
last: { rating: 902, date: 1611928398, rd: 50 },
best: {
rating: 1010,
date: 1609882454,
game: 'https://www.chess.com/live/game/6297568401'
},
record: { win: 26, loss: 24, draw: 4 }
},
fide: 0,
tactics: {
highest: { rating: 1659, date: 1609635730 },
lowest: { rating: 387, date: 1608148134 }
},
lessons: {},
puzzle_rush: {}
}
TypeError: Cannot read property 'last' of undefined
at C:\Users\Yonatan\Desktop\coding\training\intermediateChess\backend\controllers\chessStats.js:13:45
at processTicksAndRejections (internal/process/task_queues.js:93:5)
and the references I am calling are right there, so I am still stuck.
-edit 2-
I noe realized that if a player didnt play a certain game mode than the api doesnt hold that values. any ideas how to save the data as 0 or null if there is no data neatly?
Issue is in following block of code where you are trying to access last
field on different properties in response:
res.json({
daily: chessManData.chess_daily.last.rating,
rapid: chessManData.chess_rapid.last.rating,
blitz: chessManData.chess_blitz.last.rating,
bullet: chessManData.chess_bullet.last.rating,
})
I had quick look at response for following API and it does not have chess_daily
and chess_bullet
properties.
https://api.chess.com/pub/player/atomicstew/stats
Since you are trying to access chessManData.chess_daily.last.rating
and chess_daily
is not present in chessManData
, you are getting exception for .last
.
In order to fix it, you can replace above block by following:
res.json({
daily: chessManData.chess_daily && chessManData.chess_daily.last ? chessManData.chess_daily.last.rating : null, // replace null with appropriate default value for rating
rapid: chessManData.chess_rapid && chessManData.chess_rapid.last ? chessManData.chess_rapid.last.rating : null,
blitz: chessManData.chess_blitz && chessManData.chess_blitz.last ? chessManData.chess_blitz.last.rating : null,
bullet: chessManData.chess_bullet && chessManData.chess_bullet.last ? chessManData.chess_bullet.last.rating : null,
})