portada debugging en angular

Cómo gestionar errores de código en un proyecto de Angular

Última actualización:

Cuando programamos, lo habitual es que cometamos errores, tanto de sintaxis como de lógica. Arreglar esos errores y no entrar en pánico es parte del trabajo diario de un programador. Por suerte, en Angular tenemos una serie de herramientas que nos facilitan el trabajo. 👨‍🔧 ¡Veámoslas!

🤷‍♀️ ¿MÁS PERDID@ QUE UN PULPO EN UN GARAJE? 🐙

Si acabas de aterrizar aquí y estos temas de Angular te suenan a chino, te recomiendo que empieces por este artículo de introducción a Angular con las claves para entenderlo.

Vamos a trabajar con un ejemplo que puedes descargar aquí, en mi cuenta de GitHub. Para utilizarlo:

  1. Descárgatelo mediante el botón verde Clone or Download y guárdalo en el directorio de tu pc que quieras.
  2. Navega con tu terminal hasta la carpeta del proyecto y escribe el comando npm install para instalar los node_modules (las dependencias).
  3. Escribe el comando ng serve para ver la app en tu navegador. ¡Y listo!

Herramienta #1: Consola (developer tools) del navegador

Angular, a través de la consola de las dev tools de tu navegador (te recomiendo que uses Chrome), se encarga de mandarnos mensajes de alerta cada vez que existe algún tipo de error en nuestro código. Entender estos mensajes es vital para poder resolverlos

En el navegador, nuestra demo tiene esta pinta:

estado inicial debugging en angular

Con esta configuración básica, al pulsar el botón "Add counter" debería añadirse un párrafo con cada click con el mensaje que le hemos pasado en el archivo app.component.ts. Pero al pulsar, verás que no ocurre nada. Si vas a a las dev tools (y te recomiendo que siempre las tengas abiertas cuando estés escribiendo código) verás que tienes un bonito mensaje de error.

angular error undefined

Como ves, nos indica que el problema está en el app.component.ts, concretamente nos dice que la propiedad sobre la que se aplica el método push no está definida (en inglés, undefined). Además, nos marca la línea del código donde está el problema y nos lo relaciona con el método onAddCounter().

Con esta información, vamos al archivo app.component.ts a localizar el error. Allí vemos que el método push está aplicado sobre la propiedad counters, que está declarada arriba, pero no definida. ¡AHÁ! Aquí estaba el problema.

En TypeScript es obligatorio definir las propiedades antes de usarlas.
keep calm & read devtools error

 Así que simplemente definimos nuestra propiedad counters como un array vacío y problema solucionado 👏.

counters = [];

Ahora ya podemos hacer click en el botón y el resultado será el esperado, añadiéndose un párrafo a cada click, creando así una lista de elementos, uno debajo del otro. Y nuestras dev tools no nos mostrarán ningún error. 👍

Herramienta #2: Sourcemaps

A veces puede ocurrirnos que ni siquiera tengamos un mensaje de error, y que a pesar de ello, nuestro código no se comporte como esperábamos. En ese caso, es muy posible que nos encontremos ante un error de lógica. Para lidiar con ello, podemos usar los sourcemaps.

Los "sourcemaps" mapean (vinculan) los archivos finales compilados en JavaScript con sus archivos fuente creados en TypeScript.

1. Para simular este tipo de errores, creamos un método que elimine un elemento de la lista al hacer click sobre él. Lo escribimos en el app.component.ts.

  removeCounter(id: number) {
    const position = id + 1;
    this.counters.splice(position, 1);
  }
}

2. Vinculamos el método al <li> del app.component.html usando el método click.

        <li class="list-group-item"
            *ngFor="let counter of counters; let i = index"
            (click)="removeCounter(i)">
            {{counter}}
        </li>

Con esta configuración, verás que puedes añadir tantos elementos como quieras a la lista, y al hacer click sobre ellos, se eliminan. Todos menos el último, da igual que haya 10 elementos o uno solo. El último de la lista nunca se borra, y nosotros queremos que se elimine cualquier elemento al hacer click sobre él. Entonces, ¿¡por qué no funciona!? 🙄

Lo que podemos hacer es comprobar en el momento de la ejecución de nuestro código (en inglés, runtimepor qué el código no funciona. 

3. En las dev tools vamos a la pestaña Sources y dentro, a la pestaña Page. Ahí encontramos todos los archivos fuente (en inglés, sources) importados en esa página. El archivo main.js recoge todo el código TypeScript (en adelante, TS) de nuestra app  convertido a JavaScript (en adelante, JS)Ahí podemos encontrar todo el código de nuestra app, pero es poco útil si nuestro proyecto tiene muchos archivos, ya que ese archivo sería larguísimo y encontrar código ahí sería una ardua tarea. 😕

Por eso, es mejor ir directamente al archivo donde creemos que está el problema. Podemos hacerlo a través de la carpeta de webpack, como se ve en la imagen:

sourcemaps pages

4. Añadimos un punto de interrupción (en inglés, breakpoint) para que la ejecución de la función se detenga justo ahí (en la línea 17). Supongamos que has hecho click tres veces en el botón de "Add counter", así que ahora tenemos tres elementos. Cuando intentamos eliminar el último elemento de la lista, nos marca que el id de ese elemento es 2. Tiene sentido, porque en programación los índices empiezan a contar siempre desde 0. 

Así que si tenemos tres elementos, sus índices serían:

1er elemento ➡ índice = 0
2º elemento ➡ índice = 1
3er elemento ➡ índice = 2


Si continuamos la secuencia, nos indica la position actual de ese tercer elemento:

sourcemaps para debugging

¡Y ahí está el error de lógica! Porque TS está intentado localizar un elemento con índice 3, el cual no existe.

5. Vamos a hacer una pequeña modificación de nuestro código para que funcione. 

  • Eliminamos el acceso al index del loop en el archivo app.component.html, porque no nos hace falta. 
  • Dejamos de pasarle un párametro a la función removeCounter().
  <li class="list-group-item" *ngFor="let counter of counters" (click)="removeCounter()">
  • Cambiamos el contenido de la función removeCounter() por un simple método pop en el this.counters.
  removeCounter() {
    this.counters.pop();
  }

¡Y problema solucionado! 👏 Ahora se pueden eliminar todos los elementos de la lista cuando se hace click en ellos.

Herramienta #3: Augury

Augury es una extensión de Chrome, puedes conseguirla aquí. Quizás tengas que reiniciar el navegador para poder verla. La encontrarás en las dev tools, en una pestaña en la misma línea que Console, Source, etc.

 Esta herramienta diseñada especialmente para Angular nos permite tener una visión global de nuestro proyecto de Angular desde el navegador. Puedes abrirla y explorarla, verás que muestra cosas tan interesantes como las propiedades de cada componente, gráficos de las dependencias, routing y muchas cosas más, todas en un mismo sitio. 😮

THE END!

¡Y hasta aquí este artículo sobre cómo gestionar errores en Angular! Espero que hayas aprendido algo nuevo 😊.  Si te queda alguna duda, ¡nos vemos en los comentarios!

Y si crees que este post puede serle útil a alguien, ¡compártelo!

Otros artículos que pueden interesarte

Días del 353 al 386
Objetivos versus realidad Y nuevamente, llegó otro día clave. Llegó…y pasó. El pasado 4 de marzo este Reto Computer Geek[...]
Construye Minioland: Tu primera aplicación con Angular | Parte #1
¿Qué vamos a construir?Minioland, o así he decidido llamar a esta sencilla app, totalmente responsive y de tipo Single Page[...]
Angular: Entendiendo la Directiva ngModel
Angular es un framework que nos permite, entre otras cosas, añadir contenido dinámico a nuestros archivos HTML. Una de las formas[...]
Si crees que este post puede serle útil a alguien, por favor, ¡compártelo!:

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Como toda web legal que se precie, utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúas utilizando este sitio asumiremos que estás de acuerdo. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar