Update to single query model and update typing

This commit is contained in:
rui hildt 2020-07-23 10:49:24 +02:00
parent 70e3819f59
commit 09396427b2
2 changed files with 38 additions and 11 deletions

View File

@ -4,24 +4,35 @@ import { Box, TextInput } from 'grommet';
import { FormSearch } from 'grommet-icons'; import { FormSearch } from 'grommet-icons';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
const SEARCH_ARTIST = gql` import { Artists, Artist } from '../interfaces';
const QUERY_ARTIST_ALBUMS = gql`
query Artist($byName: String!) { query Artist($byName: String!) {
queryArtists(byName: $byName) { queryArtists(byName: $byName) {
name name
image
id
albums {
name
image
id
}
} }
} }
`; `;
export const SearchBox = () => { export const SearchBox = () => {
const [value, setValue] = useState(''); const [value, setValue] = useState('');
const [getArtist, { loading, data }] = useLazyQuery(SEARCH_ARTIST); const [getArtists, { data }] = useLazyQuery(QUERY_ARTIST_ALBUMS);
const [suggestions, setSuggestions] = useState(['']); const [artists, setArtists] = useState<Artists | undefined>(undefined);
// TODO: Find a solution to have suggestions not showing when empty const [suggestions, setSuggestions] = useState<string[] | undefined>(
undefined,
);
// Debounce the database query, based on the following article: // Debounce the database query, based on the following article:
// https://dev.to/reflexgravity/use-lodash-debouce-inside-a-functional-component-in-react-4g5j // https://dev.to/reflexgravity/use-lodash-debouce-inside-a-functional-component-in-react-4g5j
const updateQuery = () => { const updateQuery = () => {
getArtist({ variables: { byName: value } }); getArtists({ variables: { byName: value } });
}; };
const delayedQuery = useCallback(debounce(updateQuery, 500), [value]); const delayedQuery = useCallback(debounce(updateQuery, 500), [value]);
@ -30,6 +41,7 @@ export const SearchBox = () => {
setValue(e.target.value); setValue(e.target.value);
}; };
// TODO: Maybe merge the two use effects?
useEffect(() => { useEffect(() => {
delayedQuery(); delayedQuery();
@ -38,15 +50,16 @@ export const SearchBox = () => {
}, [value, delayedQuery]); }, [value, delayedQuery]);
useEffect(() => { useEffect(() => {
// TODO: Maybe merge the two use effects? if (data && data.queryArtists !== []) {
if (data) { // Limit artists to 5
const mapSuggestions: string[] = data.queryArtists.map( const updatedArtists = data.queryArtists.slice(0, 5);
(el: { name: string }) => { const updatedSuggestions: string[] = updatedArtists.map(
(el: Artist) => {
return el.name; return el.name;
}, },
); );
const updatedSuggestions = mapSuggestions.slice(0, 5);
setSuggestions(updatedSuggestions); setSuggestions(updatedSuggestions);
setArtists(updatedArtists);
} }
}, [data]); }, [data]);
@ -63,7 +76,7 @@ export const SearchBox = () => {
placeholder='Type an artist name' placeholder='Type an artist name'
icon={<FormSearch color='plain' />} icon={<FormSearch color='plain' />}
dropHeight='large' dropHeight='large'
suggestions= {suggestions} suggestions={suggestions}
/> />
</Box> </Box>
); );

14
src/interfaces/index.ts Normal file
View File

@ -0,0 +1,14 @@
export interface Album {
name: string;
image: string;
id: string;
}
export interface Artist {
name: string;
image: string;
id: string;
albums: Album[];
}
export type Artists = Artist[];