JavaScript – Proyecto – Almacenar textos en Local Storage

//Variables
const formulario = document.querySelector('#formulario'); //Capturo el elemento formulario en una variable
const listaTweets = document.querySelector('#lista-tweets'); //Capturo el div contenedor de los tweets en una variable


let tweets = []; //Creo el arreglo donde voy a colocar los tweets

//Eventos
eventListeners(); //Aquí le dio por llamar y crear una función que contenga los event listeners

function eventListeners() {

    //Escucho si submit para ejecutar la función agregarTweet que tomará el nuevo tweet y lo colocará en el arreglo tweets
    formulario.addEventListener('submit', agregarTweet);

    //Al cargar el DOM le asigno a tweet lo que se encuentre en local storage,
   //pero si no hay nada entonces el JSON.parse va a arrojar un null como valor,
  //con el operador OR me aseguro que coloque otra cosa en vez del null y eso tiene que ser un arreglo vacío
    //ya que más adelante hay métodos de arreglos que van a interactuar con esa variable y es necesario que exista
    //un arreglo en esa variable así esté vacía
    document.addEventListener('DOMContentLoaded', () => {
        tweets = JSON.parse( localStorage.getItem( 'tweets' )) || []; 


        insertarListaTweets(); //Llamo la función que coloca los datos del arreglo tweets en el DOM
    })
}


//Funciones
//La función que agrega el nuevo tweet al arreglo pero no todavía en el DOM, eso lo hace otra función
function agregarTweet(e) {
    //Primero: previene el evento por default debido a que esta función la manda a llamar un event tipo submit  
    e.preventDefault();
    console.log(e);
    const tweet = document.querySelector('#tweet').value; //Dos: toma lo que está escrito en el textarea del formulario

    //Tres: si el campo está vacío aborta la función con el return, manda a llamar la función que muestra el mensaje de eror
    //y le pasa un argumento a esa función que no es más que un string con un texto que describe el motivo del error
    if(tweet === '') {
        mostrarError('No hay nada escrito');
        return;
    }

    const tweetObj = { //Cuatro: crea un objeto dentro de la función con un id y el texto
        id: Date.now(),
        tweet: tweet
    }

    tweets = [...tweets, tweetObj]; //Cinco: Agrega el objeto al arreglo de objetos tweets

    formulario.reset(); //Seis: Reseteo el formulario, se quita el texto que se escribión en el textarea

    insertarListaTweets(); //Siete: Llamo la función que inserta los datos del arreglo tweets en el DOM
}

function mostrarError(error) { //Este es un mensaje de error que yo se lo quitaría,si no hay nada escrito que no pase nada
    const mensajeError = document.createElement('p');
    mensajeError.textContent = error;
    mensajeError.classList.add('error');

    const contenido = document.querySelector('#contenido');
    contenido.appendChild(mensajeError);

    setTimeout( () => {
        mensajeError.remove();
    }, 3000);
}

//Esta es la función que inserta el contenido del arreglo tweets, que es donde están todos los tweets con sus id, en el DOM
function insertarListaTweets() {

    limpiarHTML(); //Primero quita todo el contenido si hay algo previo

    if(tweets.length > 0) { //Si el arreglo global tweets tiene una longitud mayor a cero es que por lo menos tiene un objeto
        tweets.forEach( tweet => {  //Al arreglo principal le pasamos un forEach y a cada objeto lo nombramos tweet
            const btnEliminar = document.createElement('a'); //Se crea un elemento enlace <a> con...
            btnEliminar.classList.add('borrar-tweet'); //una clase específica para...
            btnEliminar.innerText = 'X'; //colocar una x que se usará para eliminar el tweet en tweet con...

            btnEliminar.onclick = () => { //ayuda del método onclic (no usamos event listner)
                borrarTweet(tweet.id); //Si se hace clic se solicita la funcion borrarTweet y se le pasa el id de tweet
            }

            const li = document.createElement('li'); //Por cada objeto en el arreglo tweets creame un elemento li
            li.innerText = tweet.tweet; //Escribe lo que está escrito en la llave tweet del objeto
            li.appendChild(btnEliminar); //Luego le mete al li el boton Eliminar creado en este mismo forEache
            listaTweets.appendChild(li); //Mete el li dentro del div correspondiente usando la variable global creada al inicio
        });
    }
    //Una vez insertado el nuevo tweet en el DOM hacemos sincronización de local storage llamando a una función para ello
    sincronizarStorage(); 
}

function sincronizarStorage() {  
    //Lo que esté en el arreglo tweets lo vuelo a poner en el local storage para que esté actualizado la próxima vez que 
    //se reinicie el navegador
    localStorage.setItem('tweets', JSON.stringify(tweets)); //Vaya que no conozco una longitud máxima
}

function borrarTweet(id) { //Para borrar un tweet si se presiona la x de eliminar tweet
    //Toma el arreglo global tweets y filtrame todos los objetos que tengan el id diferente al id que pasaron como argumento
    tweets = tweets.filter( tweet => tweet.id !== id ); 
    
    insertarListaTweets(); //E insertamos los datos del arreglo recientemente modificado de nuevo en el DOM
}

function limpiarHTML() { //La forma típica de eliminar elementos del DOM
    while(listaTweets.firstChild) { //Mientras halla hijos en listatweet elimínalo hasta que no halla ninguno
            listaTweets.removeChild(listaTweets.firstChild);
    }
}