Cuando planeas una rodada larga en motocicleta, las paradas no son opcionales: son parte esencial del viaje. Un tanque de moto promedia entre diez y quince litros, contra los sesenta de un automóvil, lo que obliga a detenerse frecuentemente para recargar gasolina, comer, tomar fotografías o simplemente estirar las piernas. Trasladar esa necesidad real a una aplicación móvil construida con Ionic y Angular es exactamente lo que se aborda aquí, paso a paso, desde la lógica del componente hasta la interfaz visual y la corrección de errores comunes.
¿Cómo funciona la lógica de waypoints en el componente?
El punto de partida es el archivo rideform.page.ts, donde se declaran dos variables fundamentales [01:10]:
- waypoints: un arreglo que almacena todas las paradas agregadas.
- masterWaypoint: una cadena de texto que representa el valor actual de la caja de entrada, es decir, la parada que el usuario está escribiendo antes de confirmarla.
La idea es sencilla: el usuario escribe el nombre de una parada en un campo de texto (masterWaypoint), presiona un botón y esa parada se transfiere al arreglo (waypoints).
¿Qué hace el método addWaypoint?
El método addWaypoint ejecuta tres acciones en secuencia [02:00]:
- Usa
this.waypoints.push(this.masterWaypoint) para agregar el contenido de la caja al arreglo.
- Limpia la variable
masterWaypoint asignándole una cadena vacía, evitando que el usuario tenga que borrar manualmente.
- Asigna el arreglo de waypoints al objeto
ride mediante this.ride.waypoints = this.waypoints, de modo que al guardar la rodada, las paradas ya estén incluidas.
Finalmente, un console.log permite verificar en la consola del navegador que el objeto ride contiene los waypoints esperados [02:45]. Es importante recordar que console es un objeto global de JavaScript, por lo que no se invoca con this.
¿Cómo se construye la interfaz visual para las paradas?
En el archivo rideform.page.html se agregan los elementos de interfaz justo debajo del campo de fecha [03:15]:
- Un
ion-item con un ion-label que muestra el texto "agregar parada".
- Un
ion-input con un placeholder (por ejemplo, "ejemplo Ciudad Victoria") vinculado a masterWaypoint mediante ngModel, que es la directiva de Angular para el two-way data binding.
- Un
ion-button alineado a la derecha con la directiva (click)="addWaypoint()" para disparar el método al hacer clic.
Un error frecuente al trabajar con ngModel es que el editor de código autocomplete la sintaxis y duplique los corchetes o paréntesis de cierre, generando un error del tipo "set attribute on element is not a valid attribute" [04:25]. La solución es revisar el HTML y eliminar los caracteres duplicados.
¿Cómo se muestra la lista de waypoints con ngFor?
Para dar feedback visual al usuario, se agrega un segundo ion-list dentro de un ion-content con un ID waypointsContainer [06:15]:
- Se utiliza la directiva ngFor con la sintaxis
let waypoint of waypoints para iterar sobre el arreglo.
- Cada parada se muestra dentro de un
ion-label con la clase ionTextWrap, que evita que nombres largos de localidades se corten visualmente.
- En el archivo SCSS correspondiente (
rideform.page.scss), se define una altura de 150 píxeles para el contenedor, permitiendo scroll cuando hay muchas paradas.
Un detalle importante: si colocas la regla CSS en el archivo equivocado (por ejemplo, en homepage.scss en lugar de rideform.page.scss), el estilo no se aplicará correctamente y elementos como el botón de guardar pueden desaparecer [08:00].
¿Cómo se resuelve el error al guardar la rodada con waypoints?
Al intentar guardar, puede aparecer el mensaje "Unexpected Token 0 in JSON at position 0" [09:10]. Este error ocurre cuando el frontend espera recibir un objeto JSON como respuesta, pero el backend devuelve algo que no lo es, como un simple "ok" sin el objeto creado.
La causa está en el controlador del backend (RideController). Aunque el método responde con ok y el objeto ride, el modelo no está devolviendo los datos recién insertados en la base de datos. La solución es encadenar un .fetch() después de la creación del registro [10:05], tal como se hace en el UserController. Con este ajuste, el servidor retorna el objeto completo de la rodada, que el frontend puede procesar correctamente como JSON.
Después de corregir el backend, basta con reiniciar el servidor con sails lift y volver a guardar la rodada. No es necesario refrescar la página del frontend porque el cambio fue exclusivamente del lado del servidor.
Con las paradas integradas en la creación de rodadas, la aplicación queda preparada para funcionalidades más avanzadas como el cálculo de distancias entre cada punto y la consulta del clima. Si te has encontrado con alguno de estos errores o tienes dudas sobre la implementación, comparte tu experiencia en los comentarios.