0

I am trying to delete some entries in FirebaseDatabase and I am having problems. The console returns the error Uncaught SyntaxError: Invalid or unexpected token only in the first entry, and for the others returns Uncaught ReferenceError: MXcLdklS39mrnk7PQEe is not defined at HTMLButtonElement.onclick.

The code is the following:

const database = firebase.database();

var imagenBanner, count;
div = document.getElementById( 'accordion' );

database.ref(`/marketing/banners`).once('value').then(function (snap) {
    count = 1;
    snap.forEach(function (childSnapshot) {
        console.log(childSnapshot.val().titulo)
        var str =`
            <div class="card">
                <div class="card-header" id="heading${count}">
                    <h5 class="mb-0">
                        <button class="btn btn-link" data-toggle="collapse" data-target="#collapse${count}" aria-expanded="true" aria-controls="collapse${count}">
                            ${childSnapshot.val().titulo}
                        </button>
                    </h5>
                </div>
            
                <div id="collapse${count}" class="collapse show" aria-labelledby="heading${count}" data-parent="#accordion">
                    <div class="card-body">
                        Introduce el banner que se mostrara al iniciar la aplicación. Especifique las imágenes y la descripción de la página.
                        <div style="margin: 20px 50px;">
                            <div class="input-group mb-3">
                                <span class="input-group-text" id="basic-addon1">Titulo</span>
                                <input id="bannerTit${childSnapshot.key}" type="text" class="form-control" placeholder="Titulo" aria-label="Titulo" aria-describedby="Titulo" value="${childSnapshot.val().titulo}">
                            </div>
                            <div class="input-group mb-3">
                                <span class="input-group-text" id="basic-addon1">Descripción</span>
                                <input id="bannerDes${childSnapshot.key}" type="text" class="form-control" placeholder="Descripción" aria-label="Descripción" aria-describedby="Descripción" value="${childSnapshot.val().descripcion}">
                            </div>
                            <div style="width:auto; margin:0 auto; text-align: center;">
                                <img src="${childSnapshot.val().imagen}" class="d-inline-block align-middle d-lg-none" style="max-width:100%; align-self: center; display: inline-block!important;" alt="">
                            </div>
                            <div class="custom-file" style="margin: auto; text-align: center;">
                                <input type="file" class="form-control" id="inputImage${childSnapshot.key}" accept="image/*">
                            </div>
                            <p style="margin: 15px 0px; text-align: end;">
                                <button class="btn btn-dark" id="guardarButton${childSnapshot.key}" class="btn btn-sm btn-outline-secondary" onclick="saveBanner(${childSnapshot.key})">Guardar Banner</button>
                                <button class="btn btn-danger" id="eliminarButton${childSnapshot.key}" class="btn btn-sm btn-outline-secondary" onclick="deleteBanner(${childSnapshot.key})">Eliminar Banner</button>
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        `;
        div.insertAdjacentHTML( 'beforeend', str );
        document.getElementById('inputImage'+childSnapshot.key).addEventListener('change', handleFileSelect, false);
        ++count;
    });
});


var storageRef = firebase.storage().ref();

function handleFileSelect(evt) {
    console.log("handleFileSelect(evt)");
    evt.stopPropagation();
    evt.preventDefault();
    file = evt.target.files[0];

    metadata = {
        'contentType': file.type
    };

    storageRef.child('banners/' + file.name).put(file, metadata).then(function(snapshot) {
        // Let's get a download URL for the file.
        snapshot.ref.getDownloadURL().then(function(url) {
            imagenBanner = url;
        });
    }).catch(function(error) {
        console.error('Upload failed:', error);
    });
}

function deleteBanner(banner) {
    console.log(banner);
    var result = confirm("Se borrara el banner de marketing. ¿Desea continuar?");
    if (result) {
        database.ref('/marketing/banners/' + banner).remove();
        location.reload();
    }
}

function saveBanner(banner) {
    console.log(banner);
    if (imagenBanner == null){
        imagenBanner = "";
    }
    database.ref('/marketing/banners/' + banner).set({
        titulo: document.getElementById("bannerTit"+banner).value,
        descripcion: document.getElementById("bannerDes"+banner).value,
        imagen: imagenBanner
    });
    location.reload();
}

function createBanner() {
    if (imagenBanner == null){
        imagenBanner = "";
    }
    database.ref('/marketing/banners/').push().set({
        titulo: document.getElementById("bannerTitNew").value,
        descripcion: document.getElementById("bannerDesNew").value,
        imagen: imagenBanner
    });
    location.reload();
}

function newBanner() {
    var str =`
        <div class="card">
            <div class="card-header" id="headingNew">
                <h5 class="mb-0">
                    <button class="btn btn-link" data-toggle="collapse" data-target="#collapseNew" aria-expanded="true" aria-controls="collapseNew">
                        Nuevo Banner
                    </button>
                </h5>
            </div>
        
            <div id="collapseNew" class="collapse show" aria-labelledby="headingNew" data-parent="#accordion">
                <div class="card-body">
                    Introduce el banner que se mostrara al iniciar la aplicación. Especifique las imágenes y la descripción de la página.
                    <div style="margin: 20px 50px;">
                        <div class="input-group mb-3">
                            <span class="input-group-text" id="basic-addon1">Titulo</span>
                            <input id="bannerTitNew" type="text" class="form-control" placeholder="Titulo" aria-label="Titulo" aria-describedby="Titulo">
                        </div>
                        <div class="input-group mb-3">
                            <span class="input-group-text" id="basic-addon1">Descripción</span>
                            <input id="bannerDesNew" type="text" class="form-control" placeholder="Descripción" aria-label="Descripción" aria-describedby="Descripción">
                        </div>
                        
                        <div class="custom-file" style="margin: auto; text-align: center;">
                            <input type="file" class="form-control" id="inputImageNew" accept="image/*">
                        </div>
                        <p style="margin: 15px 0px; text-align: end;">
                            <button class="btn btn-dark" id="guardarButtonNew" class="btn btn-sm btn-outline-secondary" onclick="createBanner()">Guardar Banner</button>
                        </p>
                    </div>
                </div>
            </div>
        </div>
    `;
    div.insertAdjacentHTML( 'afterbegin', str );
    document.getElementById('inputImageNew').addEventListener('change', handleFileSelect, false);
}

When I click the delete button from an entry, an alert is supposed to be opened, but nothing happens.

I have checked the ids of the buttons elements and all are correct and exists in the database.

I hope that someone can help me.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Sounds like you're enjoying inline event listeners and messy quoting. Don't use inline listeners, delegate the events to listen on dynamic content instead. – Teemu Apr 07 '21 at 08:11
  • To learn event delegation, take a look at [this SO post](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation), you can also read about cons of [inline listeners](https://stackoverflow.com/a/63119431/1169519). – Teemu Apr 07 '21 at 08:25
  • Thanks, I will take a look. – Emili Bellot Pulido Apr 07 '21 at 08:27
  • Apart from the parctices, your actual error is on the lines adding the last `p` element, the argument type of string (the rendered values of the placeholders) should be wrapped in the quotes in inline listeners of the buttons. – Teemu Apr 07 '21 at 08:29
  • Please can you type it? I can't find what you have said. – Emili Bellot Pulido Apr 07 '21 at 09:04
  • C'mon, you've only a single `p` tag with buttons inside it in `str` ... The second button in that tag has an inline listener: `onclick="deleteBanner(${childSnapshot.key})"` where `${childSnapshot.key}` is replaced with a string, but that string is never quoted, when it's treated as a variable at the time JS executes the handler. However, you haven't defined a variable named `MXcLdklS39mrnk7PQEe`, that's why you get the error when clicking on the delete button. – Teemu Apr 07 '21 at 09:15
  • Okay, but if I don't pass the key in the delete function, how do I know, when I click the delete button, which banner I have to delete from the database? – Emili Bellot Pulido Apr 07 '21 at 09:27
  • You can pass it, but it's a string, wrap it in the quotes! – Teemu Apr 07 '21 at 09:28
  • And, related to the event delegation, how can I check if the e.target is an input file? I only want to check if the e.target is an input file, not other types of inputs. – Emili Bellot Pulido Apr 07 '21 at 09:30
  • Check the type, `if (e.target.type === 'file') ...` – Teemu Apr 07 '21 at 09:31
  • Nice, thank you very much and sorry for being a Newby. – Emili Bellot Pulido Apr 07 '21 at 09:34
  • No worries, coding is not a basic instinct, everyone has to start from the scratch = ). – Teemu Apr 07 '21 at 09:36

0 Answers0