DEV Community

Functional Javascript
Functional Javascript

Posted on

Friday Fun Post: fetch lyrics from a public API

A simple api fetch idiom you can apply for any api.

For this particular api, there is no api key required that you must sign up for, for example like the wordnik api.

import fetchByAxiosObj from "@root/fetch/src/fetchByAxiosObj";

/*
@func
fetch lyrics by artist name (band name) and song title

@typedef {{lyrics: string}} lyricsObj
@param {string} artist
@param {string} song
@return {Promise<lyricsObj>}
*/
const fetchLyrics = async (artist, song) => await fetchByAxiosObj(`https://api.lyrics.ovh/v1/${artist}/${song}`);

Test it out

import { lpromise } from "@root/libs/src/loggers/consolelog";

//@tests
lpromise(fetchLyrics("Coldplay", "Adventure of a Lifetime"));
/*
@output
{
  lyrics: 'Turn your magic on\n' +
    "Umi she'd say\n" +
    "Everything you want's a dream away\n" +
    'And we are legends every day\n' +
    "That's what she told me\n" +
    '\n' +
    'Turn your magic on\n' +
    "To me she'd say\n" +
    "Everything you want's a dream away\n" +
    'Under this pressure, under this weight\n' +
    'We are diamonds\n' +
    '\n' +
    'I feel my heart beating\n' +
    'I feel my heart underneath my skin\n' +
    'I feel my heart beating\n' +
    'Oh, you make me feel\n' +
    "Like I'm alive again\n" +
    '(Alive again)\n' +
    'Oh, you make me feel\n' +
    "Like I'm alive again\n" +
    '\n' +
    "Said I can't go on, not in this way\n" +
    "I'm a dream that died by light of day\n" +
    'Gonna hold up half the sky and say\n' +
    'Only I own me\n' +
    '\n' +
    'I feel my heart beating\n' +
    'I feel my heart underneath my skin\n' +
    'Oh, I can feel my heart beating\n' +
    "'Cause you make me feel\n" +
    "Like I'm alive again\n" +
    '(Alive again)\n' +
    'Oh, you make me feel\n' +
    "Like I'm alive again\n" +
    '\n' +
    'Turn your magic on\n' +
    "Umi she'd say\n" +
    "Everything you want's a dream away\n" +
    'Under this pressure, under this weight\n' +
    'We are diamonds taking shape\n' +
    'We are diamonds taking shape\n' +
    '\n' +
    'Woo hoo\n' +
    'Woo hoo\n' +
    '\n' +
    "If we've only got this life\n" +
    'This adventure, oh, then I\n' +
    "And if we've only got this life\n" +
    'You get me through, ah\n' +
    "And if we've only got this life\n" +
    'In this adventure, oh, then I\n' +
    'Want to share it with you\n' +
    'With you\n' +
    'With you\n' +
    'I see you, I see you\n' +
    '\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    '\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    '\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)\n' +
    'Woo hoo (Woo hoo)'
}
*/

Notes

a.

The fetchByAxiosObj func is a simple strongly-typed wrapper around the axios fetch library.
I always wrap third-party npm libraries to enforce constraints.

b.

the lpromise func is a simple wrapper that logs the result of a promise.

Finale

If you have any questions on the pros and cons of the architectural design of this let me know.

Top comments (4)

Collapse
 
stereoplegic profile image
Mike Bybee • Edited

Using JSDoc to define types, instead of that superset thingy that everybody loves, is so bae. 😍

Collapse
 
functional_js profile image
Functional Javascript

I concur.

You know another nice benefit of JSDoc is that it forces one into the habit of documenting one's code. Every func tells a story.

All my func are documented. (Well some older one's not yet, but I'll get to them the next time I have to deal with them :)

Here's my comment snippet.

configure

in vsc -> cmd-shift-p -> Preferences: Configure User Snippets -> snippet.code-snippets
then add the json code block below
(the filename might vary. javascript.code-snippets is another common name)

usage

Put your cursor on the line above the function -> type com -> hit cmd-spacebar -> in the popup-dialog hit enter on the com entry.

"commentSnippet": {
        "scope": "javascript,typescript",
        "prefix": "com",
        "body": [
            "/**",
            "@func",
            "$1",
            "",
            "@param {$2} $3",
            "@return {$4}",
            "*/",
        ],
        "description": "comment block template for funcs"
    },
Collapse
 
stereoplegic profile image
Mike Bybee • Edited

It's so funny to me when I hear "comments are a code smell" (how dare you not assume your code is so amazing anybody can pick it up in its entirety at first glance without documentation) but pilling on extra, nonstandard syntax - both inline and in separate definitions - somehow isn't to many of the same people claiming comments "smell."

Thread Thread
 
functional_js profile image
Functional Javascript • Edited

Yes, one of the fallacies in the industry is the concept of "self-describing code".

As if just by choosing the right names for the identifiers, the code will clarify all ambiguity.

No such code will tell you "why" the code exists. And that is what most needs to be explained.