Common async / Task mistakes, and how to avoid them

The .Net async / await mechanism is a godsend when it comes to making asynchronous code accessible, but despite being a superb abstraction, there are still a lot of subtle pitfalls a lot of developers fall into.

Therefore, for this post in my series of async-themed stories I really wanted to bring in some fun (and significant) pitfalls a lot of developers (me included) regularily fall into, because they are often just so subtle to introduce, but so hard to find.

#dotnet #c-sharp-programming #csharp #asyncawait #async

What is GEEK

Buddha Community

Common async / Task mistakes, and how to avoid them

Jupyter Notebook Kernel for Running ansible Tasks and Playbooks

Ansible Jupyter Kernel

Example Jupyter Usage

The Ansible Jupyter Kernel adds a kernel backend for Jupyter to interface directly with Ansible and construct plays and tasks and execute them on the fly.

Demo

Demo

Installation:

ansible-kernel is available to be installed from pypi but you can also install it locally. The setup package itself will register the kernel with Jupyter automatically.

From pypi

pip install ansible-kernel
python -m ansible_kernel.install

From a local checkout

pip install -e .
python -m ansible_kernel.install

For Anaconda/Miniconda

pip install ansible-kernel
python -m ansible_kernel.install --sys-prefix

Usage

Local install

    jupyter notebook
    # In the notebook interface, select Ansible from the 'New' menu

Container

docker run -p 8888:8888 benthomasson/ansible-jupyter-kernel

Then copy the URL from the output into your browser:
http://localhost:8888/?token=ABCD1234

Using the Cells

Normally Ansible brings together various components in different files and locations to launch a playbook and performs automation tasks. For this jupyter interface you need to provide this information in cells by denoting what the cell contains and then finally writing your tasks that will make use of them. There are Examples available to help you, in this section we'll go over the currently supported cell types.

In order to denote what the cell contains you should prefix it with a pound/hash symbol (#) and the type as listed here as the first line as shown in the examples below.

#inventory

The inventory that your tasks will use

#inventory
[all]
ahost ansible_connection=local
anotherhost examplevar=val

#play

This represents the opening block of a typical Ansible play

#play
name: Hello World
hosts: all
gather_facts: false

#task

This is the default cell type if no type is given for the first line

#task
debug:
#task
shell: cat /tmp/afile
register: output

#host_vars

This takes an argument that represents the hostname. Variables defined in this file will be available in the tasks for that host.

#host_vars Host1
hostname: host1

#group_vars

This takes an argument that represents the group name. Variables defined in this file will be available in the tasks for hosts in that group.

#group_vars BranchOfficeX
gateway: 192.168.1.254

#vars

This takes an argument that represents the filename for use in later cells

#vars example_vars
message: hello vars
#play
name: hello world
hosts: localhost
gather_facts: false
vars_files:
    - example_vars

#template

This takes an argument in order to create a templated file that can be used in later cells

#template hello.j2
{{ message }}
#task
template:
    src: hello.j2
    dest: /tmp/hello

#ansible.cfg

Provides overrides typically found in ansible.cfg

#ansible.cfg
[defaults]
host_key_checking=False

Examples

You can find various example notebooks in the repository

Using the development environment

It's possible to use whatever python development process you feel comfortable with. The repository itself includes mechanisms for using pipenv

pipenv install
...
pipenv shell

Author: ansible
Source Code:  https://github.com/ansible/ansible-jupyter-kernel
License: Apache-2.0 License

#jupyter #python 

Samanta  Moore

Samanta Moore

1623795660

Every Java Junior does it: Common Java mistakes made by newcomers

Everyone makes mistakes, not just beginners, but even professionals. This article goes over a dozen common mistakes that Java newbies and newcomers make and how to avoid them. Have you or your colleagues made any of these common Java mistakes early in your career?

Everyone makes mistakes, not only learners or beginners, but professionals. As a programming course, CodeGym team often collects mistakes of newbies to improve our auto validator. This time we decided to interview experienced programmers about mistakes in Java they made closer to their careers start or noticed them among their young colleagues.

We collected their answers and compiled this list of dozen popular mistakes Java beginners make. The order of errors is random and does not carry any special meaning.

#articles #java #everyone makes mistakes #beginners #common mistakes #common java mistakes made by newcomers

Common async / Task mistakes, and how to avoid them

The .Net async / await mechanism is a godsend when it comes to making asynchronous code accessible, but despite being a superb abstraction, there are still a lot of subtle pitfalls a lot of developers fall into.

Therefore, for this post in my series of async-themed stories I really wanted to bring in some fun (and significant) pitfalls a lot of developers (me included) regularily fall into, because they are often just so subtle to introduce, but so hard to find.

#dotnet #c-sharp-programming #csharp #asyncawait #async

C贸mo Hacer Operaciones CRUD En JavaScript Creando Una Aplicaci贸n Todo

Hoy vamos a aprender c贸mo hacer operaciones CRUD en JavaScript creando una aplicaci贸n Todo. Empecemos 馃敟

Esta es la aplicaci贸n que estamos haciendo hoy:

Aplicaci贸n que estamos haciendo hoy

驴Qu茅 es CRUD?

descripci贸n de la imagen

CRUD significa -

  • c: crear
  • R: Leer
  • U: Actualizar
  • D: Eliminar

CRUD de forma completa

CRUD es un tipo de mecanismo que le permite crear datos, leer datos, editarlos y eliminar esos datos. En nuestro caso, vamos a crear una aplicaci贸n Todo, por lo que tendremos 4 opciones para crear tareas, leer tareas, actualizar tareas o eliminar tareas.

Comprender los principios CRUD

Antes de comenzar el tutorial, primero, comprendamos los principios CRUD. Para eso, creemos una aplicaci贸n de redes sociales muy, muy simple.

Proyecto de aplicaci贸n de redes sociales

Configuraci贸n

Configuraci贸n del proyecto

Para este proyecto, seguiremos los siguientes pasos:

  • Cree 3 archivos llamados index.html, style.css y main.js
  • Vincule el archivo JavaScript y CSS a index.html
  • Inicie su servidor en vivo

HTML

Dentro de la etiqueta del cuerpo, crea un div con un nombre de clase .container. Ah铆 tendremos 2 secciones, .lefty .right馃憞

<body>
  <h1>Social Media App</h1>
  <div class="container">

    <div class="left"></div>
    <div class="right"></div>

  </div>
</body>

En el lado izquierdo, crearemos nuestras publicaciones. En el lado derecho, podemos ver, actualizar y eliminar nuestras publicaciones. Ahora, crea un formulario dentro de la etiqueta div .left 馃憞

<div class="left">
  <form id="form">
    <label for="post"> Write your post here</label>
    <br><br>
    <textarea name="post" id="input" cols="30" rows="10"></textarea>
    <br> <br>
    <div id="msg"></div>
    <button type="submit">Post</button>
  </form>
</div>

Escribe este c贸digo dentro del HTML para que podamos mostrar nuestra publicaci贸n en el lado derecho 馃憞

<div class="right">
  <h3>Your posts here</h3>
  <div id="posts"></div>
</div>

A continuaci贸n, insertaremos el CDN font-awesome dentro de la etiqueta de encabezado para usar sus fuentes en nuestro proyecto 馃憞

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />

Ahora, vamos a hacer algunas publicaciones de muestra con 铆conos de eliminar y editar. Escribe este c贸digo dentro del div con el id #posts: 馃憞

<div id="posts">
  <div>
    <p>Hello world post 1</p>
    <span class="options">
      <i class="fas fa-edit"></i>
      <i class="fas fa-trash-alt"></i>
    </span>
  </div>

  <div >
    <p>Hello world post 2</p>
    <span class="options">
      <i class="fas fa-edit"></i>
      <i class="fas fa-trash-alt"></i>
    </span>
  </div>
</div>

El resultado hasta ahora se ve as铆:

Resultado de marcado HTML

CSS

Agregar CSS para el proyecto 1

Manteng谩moslo simple. Escribe estos estilos dentro de tu hoja de estilo: 馃憞

body {
  font-family: sans-serif;
  margin: 0 50px;
}

.container {
  display: flex;
  gap: 50px;
}

#posts {
  width: 400px;
}

i {
  cursor: pointer;
}

Ahora, escribe estos estilos para los 铆conos de opci贸n y div posteriores: 馃憞

#posts div {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.options {
  display: flex;
  gap: 25px;
}

#msg {
  color: red;
}

Los resultados hasta ahora se ven as铆: 馃憞

El resultado despu茅s de agregar el proyecto de parte css 1

Parte de JavaScript

Comenzando la parte de javascript

De acuerdo con este diagrama de flujo, seguiremos adelante con el proyecto. No te preocupes, te explicar茅 todo en el camino. 馃憞

diagrama de flujo

Validaci贸n de formulario

Primero, apuntemos a todos los selectores de ID del HTML en JavaScript. As铆: 馃憞

let form = document.getElementById("form");
let input = document.getElementById("input");
let msg = document.getElementById("msg");
let posts = document.getElementById("posts");

Luego, cree un detector de eventos de env铆o para el formulario para que pueda evitar el comportamiento predeterminado de nuestra aplicaci贸n. Al mismo tiempo, crearemos una funci贸n llamada formValidation. 馃憞

form.addEventListener("submit", (e) => {
  e.preventDefault();
  console.log("button clicked");

  formValidation();
});

let formValidation = () => {};

Ahora, vamos a hacer una declaraci贸n if else dentro de nuestra formValidationfunci贸n. Esto nos ayudar谩 a evitar que los usuarios env铆en campos de entrada en blanco. 馃憞

let formValidation = () => {
  if (input.value === "") {
    msg.innerHTML = "Post cannot be blank";
    console.log("failure");
  } else {
    console.log("successs");
    msg.innerHTML = "";
  }
};

Aqu铆 est谩 el resultado hasta ahora: 馃憞

7sb8faq21j5dzy9vlswj

Como puede ver, tambi茅n aparecer谩 un mensaje si el usuario intenta enviar el formulario en blanco.

C贸mo aceptar datos de campos de entrada

Cualesquiera que sean los datos que obtengamos de los campos de entrada, los almacenaremos en un objeto. Vamos a crear un objeto llamado data. Y crea una funci贸n llamada acceptData: 馃憞

let data = {};

let acceptData = () => {};

La idea principal es que, usando la funci贸n, recopilamos datos de las entradas y los almacenamos en nuestro objeto llamado data. Ahora terminemos de construir nuestra acceptDatafunci贸n.

let acceptData = () => {
  data["text"] = input.value;
  console.log(data);
};

Adem谩s, necesitamos que la acceptDatafunci贸n funcione cuando el usuario haga clic en el bot贸n Enviar. Para eso, activaremos esta funci贸n en la instrucci贸n else de nuestra formValidationfunci贸n. 馃憞

let formValidation = () => {
  if (input.value === "") {
    // Other codes are here
  } else {
    // Other codes are here
    acceptData();
  }
};

Cuando ingresamos datos y enviamos el formulario, en la consola podemos ver un objeto que contiene los valores de entrada de nuestro usuario. As铆: 馃憞

resultado hasta ahora en la consola

C贸mo crear publicaciones usando literales de plantilla de JavaScript

Para publicar nuestros datos de entrada en el lado derecho, necesitamos crear un elemento div y agregarlo al div de publicaciones. Primero, creemos una funci贸n y escribamos estas l铆neas: 馃憞

let createPost = () => {
  posts.innerHTML += ``;
};

Los acentos graves son literales de plantilla. Funcionar谩 como una plantilla para nosotros. Aqu铆, necesitamos 3 cosas: un div principal, la entrada en s铆 y el div de opciones que lleva los 铆conos de edici贸n y eliminaci贸n. Terminemos nuestra funci贸n 馃憞

let createPost = () => {
  posts.innerHTML += `
  <div>
    <p>${data.text}</p>
    <span class="options">
      <i onClick="editPost(this)" class="fas fa-edit"></i>
      <i onClick="deletePost(this)" class="fas fa-trash-alt"></i>
    </span>
  </div>
  `;
  input.value = "";
};

En nuestra acceptdatafunci贸n, activaremos nuestra createPostfunci贸n. As铆: 馃憞

let acceptData = () => {
  // Other codes are here

  createPost();
};

El resultado hasta ahora: 馃憞

resultado hasta ahora

Hasta ahora todo bien chicos, casi hemos terminado con el proyecto 1.

Hasta ahora, todo bien

C贸mo eliminar una publicaci贸n

Para eliminar una publicaci贸n, en primer lugar, creemos una funci贸n dentro de nuestro archivo javascript:

let deletePost = (e) => {};

A continuaci贸n, activamos esta deletePostfunci贸n dentro de todos nuestros 铆conos de eliminaci贸n usando un atributo onClick. Escribir谩 estas l铆neas en HTML y en el literal de la plantilla. 馃憞

<i onClick="deletePost(this)" class="fas fa-trash-alt"></i>

La thispalabra clave se referir谩 al elemento que dispar贸 el evento. en nuestro caso, el thisse refiere al bot贸n eliminar.

Mire con cuidado, el padre del bot贸n Eliminar es el tramo con opciones de nombre de clase. El padre del lapso es el div. Entonces, escribimos parentElementdos veces para que podamos saltar del 铆cono de eliminar al div y apuntarlo directamente para eliminarlo.

Terminemos nuestra funci贸n. 馃憞

let deletePost = (e) => {
  e.parentElement.parentElement.remove();
};

El resultado hasta ahora: 馃憞

eliminar el resultado de una publicaci贸n

C贸mo editar una publicaci贸n

Para editar una publicaci贸n, en primer lugar, creemos una funci贸n dentro de nuestro archivo JavaScript:

let editPost = (e) => {};

A continuaci贸n, activamos esta editPostfunci贸n dentro de todos nuestros 铆conos de edici贸n usando un atributo onClick. Escribir谩 estas l铆neas en HTML y en el literal de la plantilla. 馃憞

<i onClick="editPost(this)" class="fas fa-edit"></i>

La thispalabra clave se referir谩 al elemento que dispar贸 el evento. En nuestro caso, el thisse refiere al bot贸n editar.

Mire con cuidado, el padre del bot贸n de edici贸n es el tramo con opciones de nombre de clase. El padre del lapso es el div. Entonces, escribimos parentElementdos veces para que podamos saltar del 铆cono de edici贸n al div y apuntarlo directamente para eliminarlo.

Luego, cualquier dato que est茅 dentro de la publicaci贸n, lo traemos de vuelta al campo de entrada para editarlo.

Terminemos nuestra funci贸n. 馃憞

let editPost = (e) => {
  input.value = e.parentElement.previousElementSibling.innerHTML;
  e.parentElement.parentElement.remove();
};

El resultado hasta ahora: 馃憞

Editar el resultado de una publicaci贸n

隆Tomar un descanso!

Tomar un descanso

Felicitaciones a todos por completar el proyecto 1. Ahora, 隆t贸mense un peque帽o descanso!

C贸mo hacer una aplicaci贸n de tareas pendientes usando operaciones CRUD

Hagamos una aplicaci贸n de tareas

Comencemos a hacer el proyecto 2, que es una aplicaci贸n To-Do.

Configuraci贸n del proyecto

configuraci贸n del proyecto

Para este proyecto, seguiremos los siguientes pasos:

  • Cree 3 archivos llamados index.html, style.css y main.js
  • Vincule los archivos JavaScript y CSS a index.html
  • Inicie nuestro servidor en vivo

HTML

Escribe este c贸digo de inicio dentro del archivo HTML: 馃憞

<div class="app">
  <h4 class="mb-3">TODO App</h4>

  <div id="addNew" data-bs-toggle="modal" data-bs-target="#form">
    <span>Add New Task</span>
    <i class="fas fa-plus"></i>
  </div>
</div>

El div con una identificaci贸n addNewes el bot贸n que abrir谩 el modal. El intervalo se mostrar谩 en el bot贸n. El ies el 铆cono de font-awesome.

Vamos a usar bootstrap para hacer nuestro modal. Usaremos el modal para agregar nuevas tareas. Para eso, agregue el enlace CDN de arranque dentro de la etiqueta principal. 馃憞

<link
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
  rel="stylesheet"
  integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
  crossorigin="anonymous"
/>

<script
  src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
  integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
  crossorigin="anonymous"
></script>

Para ver las tareas creadas, usaremos un div con una tarea de identificaci贸n, dentro del div con la aplicaci贸n de nombre de clase. 馃憞

<h5 class="text-center my-3">Tasks</h5>

<div id="tasks"></div>

Inserte el CDN font-awesome dentro de la etiqueta principal para usar fuentes en nuestro proyecto 馃憞

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />

Copie y pegue el c贸digo a continuaci贸n que proviene del modal de arranque. Lleva un formulario con 3 campos de entrada y un bot贸n de env铆o. Si lo desea, puede buscar en el sitio web de Bootstrap escribiendo 'modal' en la barra de b煤squeda.

<!-- Modal -->
<form
  class="modal fade"
  id="form"
  tabindex="-1"
  aria-labelledby="exampleModalLabel"
  aria-hidden="true"
>
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Add New Task</h5>
        <button
          type="button"
          class="btn-close"
          data-bs-dismiss="modal"
          aria-label="Close"
        ></button>
      </div>
      <div class="modal-body">
        <p>Task Title</p>
        <input type="text" class="form-control" name="" id="textInput" />
        <div id="msg"></div>
        <br />
        <p>Due Date</p>
        <input type="date" class="form-control" name="" id="dateInput" />
        <br />
        <p>Description</p>
        <textarea
          name=""
          class="form-control"
          id="textarea"
          cols="30"
          rows="5"
        ></textarea>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          Close
        </button>
        <button type="submit" id="add" class="btn btn-primary">Add</button>
      </div>
    </div>
  </div>
</form>

El resultado hasta ahora: 馃憞

Configuraci贸n del archivo HTML

Hemos terminado con la configuraci贸n del archivo HTML. Comencemos el CSS.

CSS

Agregar la parte css

Agregue estos estilos en el cuerpo para que podamos mantener nuestra aplicaci贸n en el centro exacto de la pantalla.

body {
  font-family: sans-serif;
  margin: 0 50px;
  background-color: #e5e5e5;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Apliquemos estilo al div con la aplicaci贸n classname. 馃憞

.app {
  background-color: #fff;
  width: 300px;
  height: 500px;
  border: 5px solid #abcea1;
  border-radius: 8px;
  padding: 15px;
}

El resultado hasta ahora: 馃憞

Estilos de aplicaciones

Ahora, dise帽emos el bot贸n con el id addNew. 馃憞

#addNew {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: rgba(171, 206, 161, 0.35);
  padding: 5px 10px;
  border-radius: 5px;
  cursor: pointer;
}
.fa-plus {
  background-color: #abcea1;
  padding: 3px;
  border-radius: 3px;
}

El resultado hasta ahora: 馃憞

Agregar nueva tarea Bot贸n

Si hace clic en el bot贸n, el modal aparece as铆: 馃憞

Estallidos modales

Agregar el JS

Agregar el JavaScript

En el archivo JavaScript, en primer lugar, seleccione todos los selectores del HTML que necesitamos usar. 馃憞

let form = document.getElementById("form");
let textInput = document.getElementById("textInput");
let dateInput = document.getElementById("dateInput");
let textarea = document.getElementById("textarea");
let msg = document.getElementById("msg");
let tasks = document.getElementById("tasks");
let add = document.getElementById("add");

Validaciones de formulario

No podemos permitir que un usuario env铆e campos de entrada en blanco. Entonces, necesitamos validar los campos de entrada. 馃憞

form.addEventListener("submit", (e) => {
  e.preventDefault();
  formValidation();
});

let formValidation = () => {
  if (textInput.value === "") {
    console.log("failure");
    msg.innerHTML = "Task cannot be blank";
  } else {
    console.log("success");
    msg.innerHTML = "";
  }
};

Adem谩s, agregue esta l铆nea dentro del CSS:

#msg {
  color: red;
}

El resultado hasta ahora: 馃憞

descripci贸n de la imagen

Como puede ver, la validaci贸n est谩 funcionando. El c贸digo JavaScript no permite que el usuario env铆e campos de entrada en blanco; de lo contrario, ver谩 un mensaje de error.

C贸mo recopilar datos y utilizar el almacenamiento local

Independientemente de las entradas que escriba el usuario, debemos recopilarlas y almacenarlas en el almacenamiento local.

Primero, recopilamos los datos de los campos de entrada, usando la funci贸n named acceptDatay una matriz llamada data. Luego los empujamos dentro del almacenamiento local as铆: 馃憞

let data = [];

let acceptData = () => {
  data.push({
    text: textInput.value,
    date: dateInput.value,
    description: textarea.value,
  });

  localStorage.setItem("data", JSON.stringify(data));

  console.log(data);
};

Tambi茅n tenga en cuenta que esto nunca funcionar谩 a menos que invoque la funci贸n acceptDatadentro de la declaraci贸n else de la validaci贸n del formulario. S铆guenos aqu铆: 馃憞

let formValidation = () => {

  // Other codes are here
   else {

    // Other codes are here

    acceptData();
  }
};

Es posible que haya notado que el modal no se cierra autom谩ticamente. Para resolver esto, escribe esta peque帽a funci贸n dentro de la instrucci贸n else de la validaci贸n del formulario: 馃憞

let formValidation = () => {

  // Other codes are here
   else {

    // Other codes are here

    acceptData();
    add.setAttribute("data-bs-dismiss", "modal");
    add.click();

    (() => {
      add.setAttribute("data-bs-dismiss", "");
    })();
  }
};

Si abre las herramientas de desarrollo de Chrome, vaya a la aplicaci贸n y abra el almacenamiento local. Puedes ver este resultado: 馃憞

Resultado de almacenamiento local

C贸mo crear nuevas tareas

Para crear una nueva tarea, necesitamos crear una funci贸n, usar literales de plantilla para crear los elementos HTML y usar un mapa para insertar los datos recopilados del usuario dentro de la plantilla. S铆guenos aqu铆: 馃憞

let createTasks = () => {
  tasks.innerHTML = "";
  data.map((x, y) => {
    return (tasks.innerHTML += `
    <div id=${y}>
          <span class="fw-bold">${x.text}</span>
          <span class="small text-secondary">${x.date}</span>
          <p>${x.description}</p>
  
          <span class="options">
            <i onClick= "editTask(this)" data-bs-toggle="modal" data-bs-target="#form" class="fas fa-edit"></i>
            <i onClick ="deleteTask(this);createTasks()" class="fas fa-trash-alt"></i>
          </span>
        </div>
    `);
  });

  resetForm();
};

Tambi茅n tenga en cuenta que la funci贸n nunca se ejecutar谩 a menos que la invoque dentro de la acceptDatafunci贸n, as铆: 馃憞

let acceptData = () => {
  // Other codes are here

  createTasks();
};

Una vez que hayamos terminado de recopilar y aceptar datos del usuario, debemos borrar los campos de entrada. Para eso creamos una funci贸n llamada resetForm. S铆guenos: 馃憞

let resetForm = () => {
  textInput.value = "";
  dateInput.value = "";
  textarea.value = "";
};

El resultado hasta ahora: 馃憞

Adici贸n de tarjetas de tareas

Como puede ver, no hay estilos con la tarjeta. Agreguemos algunos estilos: 馃憞

#tasks {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

#tasks div {
  border: 3px solid #abcea1;
  background-color: #e2eede;
  border-radius: 6px;
  padding: 5px;
  display: grid;
  gap: 4px;
}

Dale estilo a los botones de editar y eliminar con este c贸digo: 馃憞

#tasks div .options {
  justify-self: center;
  display: flex;
  gap: 20px;
}

#tasks div .options i {
  cursor: pointer;
}

El resultado hasta ahora: 馃憞

Plantillas de tarjetas de estilos

Funci贸n para eliminar una tarea

Mire aqu铆 cuidadosamente, agregu茅 3 l铆neas de c贸digo dentro de la funci贸n.

  • La primera l铆nea eliminar谩 el elemento HTML de la pantalla,
  • la segunda l铆nea eliminar谩 la tarea objetivo de la matriz de datos,
  • y la tercera l铆nea actualizar谩 el almacenamiento local con los nuevos datos.
let deleteTask = (e) => {
  e.parentElement.parentElement.remove();

  data.splice(e.parentElement.parentElement.id, 1);

  localStorage.setItem("data", JSON.stringify(data));

  console.log(data);
};

Ahora cree una tarea ficticia e intente eliminarla. El resultado hasta ahora se ve as铆: 馃憞

descripci贸n de la imagen

Funci贸n para editar tareas

Mire aqu铆 cuidadosamente, agregu茅 5 l铆neas de c贸digo dentro de la funci贸n.

  • La l铆nea 1 apunta a la tarea que seleccionamos para editar
  • Las l铆neas 2, 3 y 4 apuntan a los valores [tarea, fecha, descripci贸n] de la tarea que seleccionamos para editar
  • la l铆nea 5 est谩 ejecutando la funci贸n de eliminaci贸n para eliminar los datos seleccionados tanto del almacenamiento local, el elemento HTML y la matriz de datos.
let editTask = (e) => {
  let selectedTask = e.parentElement.parentElement;

  textInput.value = selectedTask.children[0].innerHTML;
  dateInput.value = selectedTask.children[1].innerHTML;
  textarea.value = selectedTask.children[2].innerHTML;

  deleteTask(e);
};

Ahora, intente crear una tarea ficticia y ed铆tela. El resultado hasta ahora: 馃憞

Edici贸n de una tarea

C贸mo obtener datos del almacenamiento local

Si actualiza la p谩gina, notar谩 que todos sus datos han desaparecido. Para resolver ese problema, ejecutamos un IIFE (expresi贸n de funci贸n invocada inmediatamente) para recuperar los datos del almacenamiento local. S铆guenos: 馃憞

(() => {
  data = JSON.parse(localStorage.getItem("data")) || [];
  console.log(data);
  createTasks();
})();

Ahora los datos aparecer谩n incluso si actualiza la p谩gina.

Conclusi贸n

Felicidades

Felicitaciones por completar con 茅xito este tutorial. Ha aprendido a crear una aplicaci贸n de lista de tareas mediante operaciones CRUD. Ahora, puede crear su propia aplicaci贸n CRUD usando este tutorial.

Aqu铆 est谩 tu medalla por leer hasta el final. 鉂わ笍

Fuente: https://www.freecodecamp.org/news/learn-crud-operations-in-javascript-by-building-todo-app/ 

#javascript #crud #operator #todoapp

Learn CRUD Operations in JavaScript by Building TODO APP

Today we're gonna learn how to do CRUD Operations in JavaScript by making a Todo App. Let's get started 馃敟

This is the app we're making today:

App that we're making today

What is CRUD?

Image description

CRUD stands for -

  • C: Create
  • R: Read
  • U: Update
  • D: Delete

CRUD Fullform

CRUD is a type of mechanism that allows you to create data, read data, edit it, and delete those data. In our case, we're gonna make a Todo app, so we will have 4 options to create tasks, read tasks, update tasks, or delete tasks.

Understanding CRUD Principles

Before starting the tutorial, first, let's understand the CRUD principles. For that, let's create a very very simple Social Media Application.

Social Media App Project

Setup

Project Setup

For this project, we will be following these steps below:

  • Create 3 files named index.html, style.css, and main.js
  • Link the JavaScript and CSS file to index.html
  • Start your live server

HTML

Inside the body tag, create a div with a class name .container. There, we will have 2 sections, .left and .right 馃憞

<body>
  <h1>Social Media App</h1>
  <div class="container">

    <div class="left"></div>
    <div class="right"></div>

  </div>
</body>

On the left side, we will create our posts. On the right side, we can see, update, and delete our posts. Now, create a form inside the .left div tag 馃憞

<div class="left">
  <form id="form">
    <label for="post"> Write your post here</label>
    <br><br>
    <textarea name="post" id="input" cols="30" rows="10"></textarea>
    <br> <br>
    <div id="msg"></div>
    <button type="submit">Post</button>
  </form>
</div>

Write this code inside the HTML so that we can display our post on the right side 馃憞

<div class="right">
  <h3>Your posts here</h3>
  <div id="posts"></div>
</div>

Next, we'll insert the font-awesome CDN inside the head tag to use its fonts in our project 馃憞

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />

Now, we're gonna make some sample posts with delete and edit icons. Write this code inside the div with the id #posts: 馃憞

<div id="posts">
  <div>
    <p>Hello world post 1</p>
    <span class="options">
      <i class="fas fa-edit"></i>
      <i class="fas fa-trash-alt"></i>
    </span>
  </div>

  <div >
    <p>Hello world post 2</p>
    <span class="options">
      <i class="fas fa-edit"></i>
      <i class="fas fa-trash-alt"></i>
    </span>
  </div>
</div>

The result so far looks like this:

HTML Markup result

CSS

Adding CSS for project 1

Let's keep it simple. Write these styles inside your stylesheet: 馃憞

body {
  font-family: sans-serif;
  margin: 0 50px;
}

.container {
  display: flex;
  gap: 50px;
}

#posts {
  width: 400px;
}

i {
  cursor: pointer;
}

Now, write these styles for the post div and option icons: 馃憞

#posts div {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.options {
  display: flex;
  gap: 25px;
}

#msg {
  color: red;
}

The results so far look like this:馃憞

The result after adding the css part project 1

JavaScript Part

Starting the javascript part

According to this flow chart, we will go forward with the project. Don't worry, I'll explain everything along the way. 馃憞

flow chart

Form Validation

First, let's target all the ID selectors from the HTML in JavaScript. Like this: 馃憞

let form = document.getElementById("form");
let input = document.getElementById("input");
let msg = document.getElementById("msg");
let posts = document.getElementById("posts");

Then, build a submit event listener for the form so that it can prevent the default behaviour of our App. At the same time, we will create a function named formValidation. 馃憞

form.addEventListener("submit", (e) => {
  e.preventDefault();
  console.log("button clicked");

  formValidation();
});

let formValidation = () => {};

Now, we're gonna make an if else statement inside our formValidation function. This will help us prevent users from submitting blank input fields. 馃憞

let formValidation = () => {
  if (input.value === "") {
    msg.innerHTML = "Post cannot be blank";
    console.log("failure");
  } else {
    console.log("successs");
    msg.innerHTML = "";
  }
};

Here's the result so far: 馃憞

7sb8faq21j5dzy9vlswj

As you can see, a message will also show up if the user tries to submit the form blank.

How to accept data from input fields

Whatever data we get from the input fields, we will store them in an object. Let's create an object named data. And, create a function named acceptData: 馃憞

let data = {};

let acceptData = () => {};

The main idea is that, using the function, we collect data from the inputs and store them in our object named data. Now let's finish building our acceptData function.

let acceptData = () => {
  data["text"] = input.value;
  console.log(data);
};

Also, we need the acceptData function to work when the user clicks the submit button. For that, we will fire this function in the else statement of our formValidation function. 馃憞

let formValidation = () => {
  if (input.value === "") {
    // Other codes are here
  } else {
    // Other codes are here
    acceptData();
  }
};

When we input data and submit the form, on the console we can see an object holding our user's input values. Like this: 馃憞

result so far on the console

How to create posts using JavaScript template literals

In order to post our input data on the right side, we need to create a div element and append it to the posts div. First, let's create a function and write these lines: 馃憞

let createPost = () => {
  posts.innerHTML += ``;
};

The backticks are template literals. It will work as a template for us. Here, we need 3 things: a parent div, the input itself, and the options div which carries the edit and delete icons. Let's finish our function 馃憞

let createPost = () => {
  posts.innerHTML += `
  <div>
    <p>${data.text}</p>
    <span class="options">
      <i onClick="editPost(this)" class="fas fa-edit"></i>
      <i onClick="deletePost(this)" class="fas fa-trash-alt"></i>
    </span>
  </div>
  `;
  input.value = "";
};

In our acceptdata function, we will fire our createPost function. Like this: 馃憞

let acceptData = () => {
  // Other codes are here

  createPost();
};

The result so far: 馃憞

Result so far

So far so good guys, we're almost done with project 1.

so far so good

How to delete a post

In order to delete a post, first of all, let's create a function inside our javascript file:

let deletePost = (e) => {};

Next up, we fire this deletePost function inside all of our delete icons using an onClick attribute. You'll write these lines in HTML and on the template literal. 馃憞

<i onClick="deletePost(this)" class="fas fa-trash-alt"></i>

The this keyword will refer to the element that fired the event. in our case, the this refers to the delete button.

Look carefully, the parent of the delete button is the span with class name options. The parent of the span is the div. So, we write parentElement twice so that we can jump from the delete icon to the div and target it directly to remove it.

Let's finish our function. 馃憞

let deletePost = (e) => {
  e.parentElement.parentElement.remove();
};

The result so far: 馃憞

deleting a post result

How to edit a post

In order to edit a post, first of all, let's create a function inside our JavaScript file:

let editPost = (e) => {};

Next up, we fire this editPost function inside all of our edit icons using an onClick attribute. You'll write these lines in HTML and on the template literal. 馃憞

<i onClick="editPost(this)" class="fas fa-edit"></i>

The this keyword will refer to the element that fired the event. In our case, the this refers to the edit button.

Look carefully, the parent of the edit button is the span with class name options. The parent of the span is the div. So, we write parentElement twice so that we can jump from the edit icon to the div and target it directly to remove it.

Then, whatever data is inside the post, we bring it back on the input field to edit it.

Let's finish our function. 馃憞

let editPost = (e) => {
  input.value = e.parentElement.previousElementSibling.innerHTML;
  e.parentElement.parentElement.remove();
};

The result so far: 馃憞

Editing a post result

Take a Break!

Take a Break

Congratulations everyone for completing project 1. Now, take a small break!

How to Make a To-Do App using CRUD Operations

Let's make a todo app

Let's start making project 2, which is a To-Do App.

Project Setup

Project setup

For this project, we will be following these steps below:

  • Create 3 files named index.html, style.css, and main.js
  • Link the JavaScript and CSS files to index.html
  • Start our live server

HTML

Write this starter code inside the HTML file: 馃憞

<div class="app">
  <h4 class="mb-3">TODO App</h4>

  <div id="addNew" data-bs-toggle="modal" data-bs-target="#form">
    <span>Add New Task</span>
    <i class="fas fa-plus"></i>
  </div>
</div>

The div with an id addNew is the button that will open the modal. The span will be displayed on the button. The i is the icon from font-awesome.

We're going to use bootstrap to make our modal. We'll use the modal to add new tasks. For that, add the bootstrap CDN link inside the head tag. 馃憞

<link
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
  rel="stylesheet"
  integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
  crossorigin="anonymous"
/>

<script
  src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
  integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
  crossorigin="anonymous"
></script>

To see the created tasks, we'll use a div with an id tasks, inside the div with the classname app. 馃憞

<h5 class="text-center my-3">Tasks</h5>

<div id="tasks"></div>

Insert the font-awesome CDN inside the head tag to use fonts in our project 馃憞

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />

Copy and paste the code below which are from the bootstrap modal. It carries a form with 3 input fields and a submit button. If you want then you can search Bootstrap's website by writing 'modal' in the search bar.

<!-- Modal -->
<form
  class="modal fade"
  id="form"
  tabindex="-1"
  aria-labelledby="exampleModalLabel"
  aria-hidden="true"
>
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Add New Task</h5>
        <button
          type="button"
          class="btn-close"
          data-bs-dismiss="modal"
          aria-label="Close"
        ></button>
      </div>
      <div class="modal-body">
        <p>Task Title</p>
        <input type="text" class="form-control" name="" id="textInput" />
        <div id="msg"></div>
        <br />
        <p>Due Date</p>
        <input type="date" class="form-control" name="" id="dateInput" />
        <br />
        <p>Description</p>
        <textarea
          name=""
          class="form-control"
          id="textarea"
          cols="30"
          rows="5"
        ></textarea>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          Close
        </button>
        <button type="submit" id="add" class="btn btn-primary">Add</button>
      </div>
    </div>
  </div>
</form>

The result so far: 馃憞

Html file setup

We're done with the HTML file setup. Let's start the CSS.

CSS

Adding the css part

Add these styles in the body so that we can keep our app at the exact center of the screen.

body {
  font-family: sans-serif;
  margin: 0 50px;
  background-color: #e5e5e5;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Let's style the div with the classname app. 馃憞

.app {
  background-color: #fff;
  width: 300px;
  height: 500px;
  border: 5px solid #abcea1;
  border-radius: 8px;
  padding: 15px;
}

The result so far: 馃憞

App styles

Now, let's style the button with the id addNew. 馃憞

#addNew {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: rgba(171, 206, 161, 0.35);
  padding: 5px 10px;
  border-radius: 5px;
  cursor: pointer;
}
.fa-plus {
  background-color: #abcea1;
  padding: 3px;
  border-radius: 3px;
}

The result so far: 馃憞

Add new task Button

If you click on the button, the modal pops up like this: 馃憞

Modal poping

Add the JS

Adding the JavaScript

In the JavaScript file, first of all, select all the selectors from the HTML that we need to use. 馃憞

let form = document.getElementById("form");
let textInput = document.getElementById("textInput");
let dateInput = document.getElementById("dateInput");
let textarea = document.getElementById("textarea");
let msg = document.getElementById("msg");
let tasks = document.getElementById("tasks");
let add = document.getElementById("add");

Form Validations

We cannot let a user submit blank input fields. So, we need to validate the input fields. 馃憞

form.addEventListener("submit", (e) => {
  e.preventDefault();
  formValidation();
});

let formValidation = () => {
  if (textInput.value === "") {
    console.log("failure");
    msg.innerHTML = "Task cannot be blank";
  } else {
    console.log("success");
    msg.innerHTML = "";
  }
};

Also, add this line inside the CSS:

#msg {
  color: red;
}

The result so far: 馃憞

Image description

As you can see, the validation is working. The JavaScript code doesn't let the user submit blank input fields, otherwise you're gonna see an error message.

How to collect data and use local storage

Whatever inputs the user writes, we need to collect them and store them in local storage.

First, we collect the data from the input fields, using the function named acceptData and an array named data. Then we push them inside the local storage like this: 馃憞

let data = [];

let acceptData = () => {
  data.push({
    text: textInput.value,
    date: dateInput.value,
    description: textarea.value,
  });

  localStorage.setItem("data", JSON.stringify(data));

  console.log(data);
};

Also note that this will never work unless you invoke the function acceptData inside the else statement of the form validation. Follow along here: 馃憞

let formValidation = () => {

  // Other codes are here
   else {

    // Other codes are here

    acceptData();
  }
};

You may have noticed that the modal doesn't close automatically. To solve this, write this small function inside the else statement of the form validation: 馃憞

let formValidation = () => {

  // Other codes are here
   else {

    // Other codes are here

    acceptData();
    add.setAttribute("data-bs-dismiss", "modal");
    add.click();

    (() => {
      add.setAttribute("data-bs-dismiss", "");
    })();
  }
};

If you open Chrome dev tools, go to the application and open the local storage. You can see this result: 馃憞

Local Storage Result

How to create new tasks

In order to create a new task, we need to create a function, use template literals to create the HTML elements, and use a map to push the data collected from the user inside the template. Follow along here: 馃憞

let createTasks = () => {
  tasks.innerHTML = "";
  data.map((x, y) => {
    return (tasks.innerHTML += `
    <div id=${y}>
          <span class="fw-bold">${x.text}</span>
          <span class="small text-secondary">${x.date}</span>
          <p>${x.description}</p>
  
          <span class="options">
            <i onClick= "editTask(this)" data-bs-toggle="modal" data-bs-target="#form" class="fas fa-edit"></i>
            <i onClick ="deleteTask(this);createTasks()" class="fas fa-trash-alt"></i>
          </span>
        </div>
    `);
  });

  resetForm();
};

Also note that the function will never run unless you invoke it inside the acceptData function, like this: 馃憞

let acceptData = () => {
  // Other codes are here

  createTasks();
};

Once we're done collecting and accepting data from the user, we need to clear the input fields. For that we create a function called resetForm. Follow along: 馃憞

let resetForm = () => {
  textInput.value = "";
  dateInput.value = "";
  textarea.value = "";
};

The result so far: 馃憞

Adding task cards

As you can see, there's no styles with the card. Let's add some styles: 馃憞

#tasks {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

#tasks div {
  border: 3px solid #abcea1;
  background-color: #e2eede;
  border-radius: 6px;
  padding: 5px;
  display: grid;
  gap: 4px;
}

Style the edit and delete buttons with this code: 馃憞

#tasks div .options {
  justify-self: center;
  display: flex;
  gap: 20px;
}

#tasks div .options i {
  cursor: pointer;
}

The result so far: 馃憞

Styles card templates

Function to delete a task

Look here carefully, I added 3 lines of code inside the function.

  • The first line will delete the HTML element from the screen,
  • the second line will remove the targetted Task from the data array,
  • and the third line will update the local storage with the new data.
let deleteTask = (e) => {
  e.parentElement.parentElement.remove();

  data.splice(e.parentElement.parentElement.id, 1);

  localStorage.setItem("data", JSON.stringify(data));

  console.log(data);
};

Now create a dummy task and try to delete it. The result so far looks like this: 馃憞

Image description

Function to edit tasks

Look here carefully, I added 5 lines of code inside the function.

  • Line 1 is targetting the task that we selected to edit
  • Lines 2, 3, and 4, are targetting the values [task, date, description] of the task that we selected to edit
  • line 5 is running the delete function to remove the selected data both from the local storage, HTML element, and data array.
let editTask = (e) => {
  let selectedTask = e.parentElement.parentElement;

  textInput.value = selectedTask.children[0].innerHTML;
  dateInput.value = selectedTask.children[1].innerHTML;
  textarea.value = selectedTask.children[2].innerHTML;

  deleteTask(e);
};

Now, try to create a dummy task and edit it. The result so far: 馃憞

Editing a Task

How to get data from local storage

If you refresh the page, you'll note that all of your data is gone. In order to solve that issue, we run a IIFE (Immediately invoked function expression) to retrieve the data from local storage. Follow along: 馃憞

(() => {
  data = JSON.parse(localStorage.getItem("data")) || [];
  console.log(data);
  createTasks();
})();

Now the data will show up even if you refresh the page.

Conclusion

Congratulations

Congratulations for successfully completing this tutorial. You've learned how to create a todo list application using CRUD operations. Now, you can create your own CRUD application using this tutorial.

Here's your medal for reading until the end. 鉂わ笍

Source: https://www.freecodecamp.org/news/learn-crud-operations-in-javascript-by-building-todo-app/

#javascript #crud #operator #todoapp