#Is it possible to check data from API in a cleaner way?

7 messages · Page 1 of 1 (latest)

visual ferry
#

Hello there,
I'm currently getting data from spotify's api through a function I have named GetSongsFromPlaylist (https://api.spotify.com/v1/playlists/). when I have gotten the data I need to check if the data I want exists, but is it possible to do it without these massive if statements?

if (
  typeof formData.get('countryCode') !== 'string' ||
  typeof formData.get('playlist') !== 'string'
) {
  return false;
}
const playlistData: unknown = await GetSongsFromPlaylist(
  formData.get('countryCode') as string,
  formData.get('playlist') as string
);
if (
  typeof playlistData !== 'object' ||
  !playlistData ||
  !('tracks' in playlistData) ||
  typeof playlistData.tracks !== 'object' ||
  !playlistData.tracks ||
  !('items' in playlistData.tracks) ||
  !playlistData.tracks.items ||
  !Array.isArray(playlistData.tracks.items)
) {
  return false;
}

const songIds = playlistData.tracks.items.map((item: unknown) => {
  if (
    typeof item === 'object' &&
    item &&
    'track' in item &&
    typeof item.track === 'object' &&
    item.track &&
    'id' in item.track
  ) {
    return item.track.id;
  }
})
ionic bear
#

@visual ferry Yeah, basically two options:

  1. You can use a data validation library (e.g. zod) where you define the schema that you expect and then it provides validation methods for you.
  2. You could just define the type you expect and cast it.
#

"Just cast it" isn't 'safe', TS won't be able to check that the data you get actually matches the type ("TS doesn't exist at runtime") but in a lot of cases, it's fine to just assume the API returns the data that it claims.

#

I guess option 3 is "look for some typed SDK that exposes JS functions instead of manually calling the endpoints"

#

BTW, you can clean this up a bit:

const countryCode = formData.get('countryCode');
const playlist = formData.get('playlist');
if (
  typeof countryCode !== 'string' ||
  typeof playlist !== 'string'
) {
  return false;
}
const playlistData: unknown = await GetSongsFromPlaylist(countryCode, playlist);
#

TS can't narrow formData.get('countryCode') (it could return a different thing on each call, as far as TS knows); but it can narrow a variable.

visual ferry
#

thanks for the help, i appreciate it heart002