import React, { useState, useCallback, useEffect } from 'react'; import { Grommet } from 'grommet'; import { debounce } from 'lodash'; import { gql, useLazyQuery } from '@apollo/client'; import { Header } from './Header'; import { Search } from './Search'; import { Results } from './Results'; import { Artists, Artist } from '../interfaces'; const QUERY_ARTISTS = gql` query Artist($byName: String!) { queryArtists(byName: $byName) { name image id albums { name image id } } } `; export default function App() { const [inputValue, setInputValue] = useState(''); const [getArtists, { data }] = useLazyQuery(QUERY_ARTISTS); const [artists, setArtists] = useState(undefined); const [suggestions, setSuggestions] = useState( undefined, ); const [selected, setSelected] = useState(false); // Debounce the database query // Based on: https://archive.is/wip/6JDqb const updateQuery = () => { getArtists({ variables: { byName: inputValue } }); }; const delayedQuery = useCallback(debounce(updateQuery, 500), [inputValue]); const handleChange = (e: React.ChangeEvent) => { setInputValue(e.target.value); }; useEffect(() => { delayedQuery(); // Cancel previous debounce calls during useEffect cleanup. return delayedQuery.cancel; }, [inputValue, delayedQuery]); const handleSelect = (suggestion: any) => { const selectedName: string = suggestion.suggestion; const suggestedArtists = data.queryArtists.slice(0, 5); let updatedArtists: Artists; // Find the selected artist and move it to index 0 for (let i = 0; i < suggestedArtists.length; i++) { if (suggestedArtists[i].name === selectedName) { const selectedArtist: Artists = suggestedArtists?.splice(i, 1); const otherArtists: Artists = suggestedArtists; updatedArtists = [...selectedArtist!, ...otherArtists!] break; } } setArtists(updatedArtists); setSelected(true); }; useEffect(() => { // TODO optimize re-rendering, probably by using onCompleted instead of this useEffect // See https://github.com/apollographql/apollo-client/issues/5268#issuecomment-596950174 if (data && data.queryArtists !== []) { // Limit artists to 5 const updatedArtists = data.queryArtists.slice(0, 5); const updatedSuggestions: string[] = updatedArtists.map( (el: Artist) => { return el.name; }, ); setSuggestions(updatedSuggestions); // setArtists(updatedArtists); } }, [data]); return (

Spoti Search

{selected && }
); } const theme = { global: { font: { family: 'Roboto', size: '18px', height: '20px', }, }, };