Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The spinner does not remove after fetch api

I have this song lyrics app, the problem is the spinner does not remove after the api fetch. it is like javascript does not detect the spinner already exist, but it exist! when I call the remove function.

If I remove the conditional:

if(spinnerHtml) {
   spinnerHtml.remove();
};

and only leave this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

spinnerHtml.remove();

so I get this error:
TypeError: Cannot read properties of null (reading ‘remove’).

const form = document.querySelector("#formulario-buscar");
const artistInput = document.querySelector("#artista");
const songInput = document.querySelector("#cancion");
const searchBtn = document.querySelector("#buscar");
const divMessages = document.querySelector("#mensajes");
const divResult = document.querySelector("#resultado");
const headingSong = document.querySelector("#song-name");


function spinner() {
    const spinner = document.createElement("div");
    spinner.classList.add('spinner');
    spinner.setAttribute('id', 'spinner');
    spinner.innerHTML = `
    <div class="rect1"></div>
    <div class="rect2"></div>
    <div class="rect3"></div>
    <div class="rect4"></div>
    <div class="rect5"></div>
    `;
    form.insertBefore(spinner, document.querySelector(".enviar"));
}


let spinnerExist = false;

form.addEventListener("submit", searchSong);


function searchSong(e) {
    e.preventDefault();


        //show spinner
   if(spinnerExist === false) {
       spinner(); 
       spinnerExist = true;
   };

   //consult our API
  const query = new API(artistInput.value,            songInput.value)
  query.consultApi();
}

const spinnerHtml = document.getElementById('spinner');

class API {
    constructor(artist, song) {
        this.artist = artist;
        this.song = song;
    }

    async consultApi() {
        const url = `https://api.lyrics.ovh/v1/${this.artist}/${this.song}`;
        
        try {
            const response = await fetch(url);
            const result = await response.json();
          
            // //when it found the lyrics it delete the spinner
            if(spinnerHtml) {
                spinnerHtml.remove();
            };
            
            
            const {lyrics} = result;

            //here we assign the song lyrics to the DOM
            divResult.textContent = lyrics;
            headingSong.textContent = `Lyrics of ${this.song} from the artist ${this.artist}`;

        } catch (error) {

            console.log(error);
            divMessages.textContent = error;
            divMessages.classList.add("error");

            setTimeout(() => {
                divMessages.textContent = "";
                divMessages.classList.remove("error");
            }, 3000);
        }
    }
}
html{
    min-height: 100%;
    box-sizing: border-box;
}
*, *:before, *:after {
    box-sizing: inherit;
}

body {
    background-image: linear-gradient(to top, #1e3c72 0%, #1e3c72 1%, #2a5298 100%);
    font-family: 'Montserrat', sans-serif;
    min-height: 100%;
}
h1 {
    font-weight: 400;
    text-align: center;
}
h2 {
    text-align: center;
}

.contenido {
    background-color: white;
    max-width: 1100px;
    margin:  0 auto;
    height: 100%;
    padding: 20px;
}


@media (min-width:768px) {
    .contenedor {
        display: flex;
        flex-wrap: wrap;
    }
    .contenedor > div {
        flex: 1 0 50%;
    }
}
.formulario-busqueda p {
    text-align: center;
}
.formulario-busqueda span {
    color: red;
}

.input {
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
}
.input label {
    flex: 0 0 120px;
    text-align: right;
    margin-right: 1rem;
    font-weight: 700;
    text-transform: uppercase;
}
.input span {
    color: red;
}
.input input[type="text"] {
    height: 2.5rem;
    padding: 1rem;
    display: flex;
    flex: 1;
}
.enviar {
    text-align: center;
    justify-content: center;
}
.input input[type="submit"]{
    background-color: #6f86d6;
    padding: .5rem 2rem;
    color: white;
    align-self: flex-end;
    border:none;
    transition: background-color .3s ease-in-out;
} 
.input input[type="submit"]:hover {
    cursor: pointer;
    background-color: #384e9d;
}

.error {
    padding: 1rem;
    border: 1px solid red;
    background-color: rgb(249, 121, 121);
    color: white;
    text-align: center;
}


#resultado {
    white-space: pre-wrap;
    padding: 2rem;
}

.spinner {
    margin: 100px auto;
    width: 50px;
    height: 40px;
    text-align: center;
    font-size: 10px;
  }
  
  .spinner > div {
    background-color: #333;
    height: 100%;
    width: 6px;
    display: inline-block;
    
    -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
    animation: sk-stretchdelay 1.2s infinite ease-in-out;
  }
  
  .spinner .rect2 {
    -webkit-animation-delay: -1.1s;
    animation-delay: -1.1s;
  }
  
  .spinner .rect3 {
    -webkit-animation-delay: -1.0s;
    animation-delay: -1.0s;
  }
  
  .spinner .rect4 {
    -webkit-animation-delay: -0.9s;
    animation-delay: -0.9s;
  }
  
  .spinner .rect5 {
    -webkit-animation-delay: -0.8s;
    animation-delay: -0.8s;
  }
  
  @-webkit-keyframes sk-stretchdelay {
    0%, 40%, 100% { -webkit-transform: scaleY(0.4) }  
    20% { -webkit-transform: scaleY(1.0) }
  }
  
  @keyframes sk-stretchdelay {
    0%, 40%, 100% { 
      transform: scaleY(0.4);
      -webkit-transform: scaleY(0.4);
    }  20% { 
      transform: scaleY(1.0);
      -webkit-transform: scaleY(1.0);
    }
  }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Buscador de Letras - JSModerno</title>
    <link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.0/normalize.css">
    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,900" rel="stylesheet">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

    <main id="contenido" class="contenido">
            <h1>Letras de Canciones</h1>
            <div class="contenedor">
                    <div id="buscar" class="buscar">
                            <h2>BĂşsqueda</h2>
                            <p>Busca por artista y nombre:</p>
                            <p><span> * </span>Obligatorio</p>
                            <form action="#" id="formulario-buscar">
                                <div class="input">
                                    <label for="artista">Artista: <span>*</span></label>
                                    <input type="text" id="artista" placeholder="Artista">
                                </div>
                                <div class="input">
                                    <label for="cancion">CanciĂłn: <span>*</span></label>
                                    <input type="text" id="cancion" placeholder="Nombre CanciĂłn">
                                </div>

                                <div class="input enviar">
                                    <input type="submit" id= "buscar" value="Buscar">
                                </div>
                            </form>
                    </div>
                    
                    <div class="letra-resultado">
                            <h2 id="song-name"></h2>
                            <div id="resultado"></div>
                    </div>
                    <div id="mensajes"></div>
            </div>
    </main>

    
    <script src="js/app.js"></script>
</body>
</html>

>Solution :

I think it’s a bad practice to use out-of-scope variables inside classes. It looks like the variable spinnerHtml is not accessible to the class function consultApi. Try selecting the element inside the class function consultApi with the query again.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading