Skip to content

Instantly share code, notes, and snippets.

@drzhbe
Last active June 28, 2019 13:12
Show Gist options
  • Save drzhbe/f0b862483ea87573eea36702219f1c61 to your computer and use it in GitHub Desktop.
Save drzhbe/f0b862483ea87573eea36702219f1c61 to your computer and use it in GitHub Desktop.
Misha lastfm api
const API_KEY = 'eee301d58fa69f9c700b2aadfb915a71';
const BASE_URL = 'http://ws.audioscrobbler.com/2.0';
/* Fetch data */
function fetchArtist(artist) {
const searchParams = `artist=${artist}&api_key=${API_KEY}&format=json`;
fetch(`${BASE_URL}/?method=artist.gettopalbums&limit=5&${searchParams}`)
.then(async response => {
if (response.status !== 200) {
return;
}
const data = await response.json();
store.albumsMeta.set(data.topalbums.album);
// Fetch the albums content
const requests = store.albumsMeta.value.map(album =>
fetch(`${BASE_URL}/?method=album.getinfo&album=${album.name}&${searchParams}`)
.then(async response => {
if (response.status !== 200) {
return;
}
const data = await response.json();
return data;
})
);
const albums = await Promise.all(requests);
store.albumsData.set(albums);
});
fetch(`${BASE_URL}/?method=artist.getTopTracks&limit=15&${searchParams}`)
.then(async response => {
if (response.status !== 200) {
return;
}
const data = await response.json();
store.tracks.set(data.toptracks.track);
});
fetch(`${BASE_URL}/?method=artist.getinfo&lang=ru&${searchParams}`)
.then(async response => {
if (response.status !== 200) {
return;
}
const data = await response.json();
store.bio.set(data.artist.bio);
});
}
/* Utilities */
function getRandomItem(array) {
return array[Math.floor(Math.random()*array.length)];
}
class Observable {
constructor() {
this.value = undefined;
this.callbacks = [];
}
onChange(callback) {
this.callbacks.push(callback);
}
set(value) {
this.value = value;
this.callbacks.forEach(cb => cb(value));
}
}
/* Init */
const placeholders = [
'nirvana', 'metallica', 'the doors', 'кино', 'u2',
'сплин', 'ддт', 'the cure', 'soundgarden', 'nin', 'психея',
];
const searchInput = document.querySelector('.searchInput');
searchInput.placeholder = `Например ${getRandomItem(placeholders)}`;
document.querySelector('.searchButton').addEventListener('click', () => {
fetchArtist(searchInput.value);
});
document.addEventListener('keydown', (e) => {
if (e.keyCode === 13) { // enter
fetchArtist(searchInput.value);
}
});
const store = {
albumsMeta: new Observable(),
albumsData: new Observable(),
tracks: new Observable(),
bio: new Observable(),
};
/* Render the data from the store */
store.albumsMeta.onChange(albums => {
const html = albums.map(album => {
const name = album.name === '(null)'
? 'с этим альбомом что то не так'
: album.name;
const image = album.image[3]['#text'] || 'https://pp.userapi.com/smNSUs97pLs2BT0jiiKIdEy6uaCJ3lHadeuJsw/qnlRTo3pAb8.jpg?ava=1';
return `<div class='item-album'><a href=${album.url}><div>${name}</div></a><img src=${image}></div>`;
});
document.querySelector('.albums').innerHTML = html.join('');
});
store.albumsData.onChange(albums => {
const albumNodes = document.querySelectorAll('.item-album');
albums.forEach((album, i) => {
const tracksNode = document.createElement('ul');
album.album.tracks.track.forEach(track => {
const li = document.createElement('li');
li.classList.add('album-track');
li.innerText = track.name;
tracksNode.appendChild(li);
});
const albumNode = albumNodes[i];
albumNode.appendChild(tracksNode);
});
});
store.tracks.onChange(tracks => {
const html = tracks.map(({ url, name, playcount }) =>
`<li><a href=${url}>${name}</a> прослушиваний ${playcount}</li>`
);
document.querySelector('.tracks').innerHTML = html.join('');
});
store.bio.onChange(bio => {
document.querySelector('.bio').innerHTML = bio.content || `We know nothing about this artist`;
});
<!DOCTYPE html>
<html>
<head>
<title>Search your artist</title>
</head>
<body>
<div class="app">
<div class='searchLabel'>Введите название исполнителя</div>
<input type="text" class='searchInput'>
<button class='searchButton'>Найти</button>
<h2>Топ 5 альбомов</h2>
<div class='albums'></div>
<h2>Топ 15 песен</h2>
<div class='tracks'></div>
<h2>Биография</h2>
<div class='bio'></div>
</div>
<script src='app.js'></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment