Actualizando nuestro index.html para agregar la nueva funcionalidad de routing
Clase 12 de 13 • Taller de Creación de Router para Single Page App con JavaScript
Contenido del curso
Clase 12 de 13 • Taller de Creación de Router para Single Page App con JavaScript
Contenido del curso
Francisco Javier Araujo de la Garza
HENRY DSANTIAGO
Lluis Pitarch Ripolles
Andrés David Solarte Vidal
Angelo Zambrano
Ivan Santiago
Angelo Zambrano
Guillermo Castaño Vèlez
Jose Luis Higuera Caraveo
Jorge Méndez Ortega
Diego Valenzuela
Sergio Estrella
Miguel Angel Muñoz Pozos
Ricardo Celis
Jose Luis Gutierrez Carcausto
Jose Morales Varon
Diego Lozano
Jimmy Buriticá Londoño
Vicente
Alexei Alvarez
Gonzalo Pimentel
Jose Morales Varon
Manuel Entrena Jimenez
Jose Oliva Rivera
Wanda Peruzzo
Wanda Peruzzo
Javier Romero
Alex Camacho
Javier Romero
Javier Romero
Richard Anthony Aguilar Montaño
Alex Camacho
Juan José Mamani Tarqui
Jhon Alexander Alvarez Romero
Jorge Méndez Ortega
Juan Diego Bohorquez Quiroga
Me gustaria que fuera mas practico, ir estructurando en orden el codigo y explicar que se hace en cada seccion. Por ejemplo: con esta funcion guardamos el path de la url actual y en ese momento hacer una prueba imprimiendo la ruta por consola.
Tenía un problema, se me generaba el error "Uncaught TypeError: Cannot read property 'template' of undefined". Esto se generaba porque se cargaba la ruta "localhost:8000/index.html", la cual no estaba en nuestro archivo routes.js, entonces hay 2 maneras de solucionarlo, o agregas esa ruta a routes.js o simplemente borras el "index.html" de la url y tu página cargará sin problemas.
Gracias tenía el mismo error y no encontraba la forma de solucionarlo
Muchas gracias.
Realmente no me funcionó como el profe lo hizo. Aquí va mi solución, espero les sirva:
Excelente! ¿Qué significa el "$1" en el replace() en el que usaste expresiones regulares?
Hola @lewss
Súper sencillo:
El replace() está recibiendo en el primer parámetro una expresión regular, que es lo que quiero remplazar:
replace(/(regEx)/)Como segundo parámetro es por lo que quiero que se remplace:
replace(/(regEx)/, "$1")Este $1 es parte de las expresiones regulares, simplemente toma lo que esté dentro del primer paréntesis. Por ejemplo:
replace(/Hola (mundo)/, "$1")Aquí el $1 sería igual a mundo
Me molesta como en las clases de programación empiezan a escribir código y hay que seguirlo, se saltan por completo la lógica. El método de Freddy con la tablet donde primero explica TOOOOOODOOOO lo que pasa en el programa y luego empieza a codear es perfecto, no se porque no se lo exigen a todos los profesores, sobre todos los de js..que insisto...empiezan a agregar código y por alguna razón piensan que los que estamos aprendiendo les podemos seguir el ritmo.
Concuerdo contigo. En ocasiones tengo que tomar la clase hasta 3 veces para poder medio entender la lógica. Pero definitivamente este profesor necesita mejorar su forma de enseñar. De todos, es al que menos le he entendido.
La solución creo que esta un poco rebuscada, les comparto mi solución
Path.js
const PATHS = { home: { path: "/", template: "<h1>Home 🏠</h1>", }, about: { path: "/about", template: "<h1>Sobre mi 👨🏻💻</h1>", }, contact: { path: "/contact", template: "<h1>Contacto 📲</h1>", }, error: { path: "/", template: "<h1>Error ⛔️</h1>", }, }
Router.js
class Router { /** * Metodo inicial. * * @return {void}. */ constructor(paths) { this.paths = paths; this.initRouter(); } /** * Permite inicializar el router * * @return {void}. */ initRouter() { const { location: { pathname = "/" } } = window; const URI = pathname === "/" ? "home" : pathname.replace("/", ""); this.load(URI); } /** * Permite iniciar la carga de paginas. * * @return {void}. */ load(page = "home") { const { paths } = this; const { path, template } = paths[page] || paths.error; const $CONTAINER = document.querySelector("#content"); $CONTAINER.innerHTML = template; window.history.pushState({ }, "Genial", path); } } const ROUTER = new Router(PATHS);
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Manejo de Routers</title> </head> <body> <header> <nav> <ul> <li> <button id="Home" onclick="ROUTER.load('home')">Home</button> </li> <li> <button id="About" onclick="ROUTER.load('about')">About</button> </li> <li> <button id="Contact" onclick="ROUTER.load('contact')">Contact</button> </li> </ul> </nav> </header> <section> <div id="content"> </div> </section> <footer></footer> <script src="./Paths.js"></script> <script src="./Router.js"></script> </body> </html>
que grande, este código si funciona, la verdad es que el curso estaba muy poco didáctico
Con esa explicación del final me quedó más claro lo que estábamos haciendo! :D
mi ejemplo de lo aprendido en este curso yo agregue botones con class de **bootstrap **
Esoooo Gran upgrade al proyecto Miguel! Te gustó el curso?
Yepaaaaa!!!! al fin se probara el código, vaya mas mierda de profe
De paso el codigo no funciona
Hola compañeros, me pasó que si escribo una ruta que no existe, el programa se rompe, para resolver el error, agregué en la función _matchUrlToRoute una condición antes del return que devuelve un objeto con solo la propiedad template
if (matchedRoute === undefined) { return { template: '<h1>Not found</h1>' }; } return matchedRoute;
Buena idea, me gusta esta opción. La probé y funciona muy bien.
Me ha gustado mucho el curso y creo que es bastante útil: Felicito al profesor por su entusiasmo y la materia aportada pero creo que debería haberlo preparado mejor. Por ejemplo, ir probando resulatdos parciales y no esperar hasta el final para que todo funcione con el último return. Algunas explicaciones también dejan algo que desear. Espero que se tome mi comentario como una critica constructiva alejada por supuesto de la intencionalidad de comunuicar una verdad absoluta y de nuevo le doy las gracias al profesor por haberme ayudaddo a aprender. Pero Platzi no es cualquier academia sino la puerta abierta del conocimiento digital a muchísima gente. Si entre todos conseguimos que sea aún mejor de lo que es, nos beneficiaremnos por partida boble o tal vez triple.
Saludos Vicent
Si les sirve. Me tope con el error "router is not defined", y me encontré con que el error o mi error se estaba en el onclick, que utilizábamos en html.
En lugar de eso lo hice de esta forma.
Un gran curso la verdad, me gusta la lógica con la que el profesor trabaja y aprendí nuevos conceptos de JS. Me funcionó todo perfecto, acá les dejo mi código. index.html
Me sirvió de mucho tu ejemplo, resolví varios problemas que tenía gracias.
He creado mi propia solucion porque no me iba el evento onclick
<body> <header> <ul> <li> <button data-router="">Home</button> </li> <li> <button data-router="portfolio">PorFolio</button> </li> <li> <button data-router="aboutme">About Me</button> </li> <li> <button data-router="contact">Contact</button> </li> </ul> </header> <div id="root"></div> <script src="./index.js" type="module"></script> </body>
const routerOutElm = document.querySelector("#root");
import Router from "./router.js"; import { routes } from "./routes.js"; /* Seleccionamos los botones */ const btnListRoute = [...document.querySelectorAll("[data-router]")]; /* Genero eventos Cliks del menu de navegación */ btnListRoute.forEach((btn) => { btn.addEventListener("click", () => { router.loadRoute(btn.dataset.router); }); }); /* Declaro la instancia de Router */ const router = new Router(routes);```
Esto con parametros dinamicos es mucho? Deberia hacer una app siempre que necesite parametros dinamicos? … o es posible hacerlo asi de sencillo. Es que solo son 4 paginas pero necesito parametros en la url.
Esto con parametros dinamicos es mucho? Deberia hacer una app siemplre que necesite parametros dinamicos .. es que solo son 4 paginas pero necesito parametros en la url.. que piensan?
pregunta que es template y para que sirve eso ?
Hola Javi, Un template es son las áreas donde van los bloques del contenido de nuestra página y su funcionalidad está en poder indicar desde nuestro JS qué vamos a enviar y mostrar en el HTML.
no entiendo cuales son los bloques de contenido ? podrías darme un ejemplo por favor...
una pregunta porque ese servidor http no se recarga automáticamente como se hacia en live-server ? ósea me refiero a que porque tenemos que volver a ejecutarlo desde la terminal, esa es mi pregunta.
Has probado con nodemon? Es un modulo de NodeJs que refrescas el servidor al ejecutarse como un Middleware cuando se piden peticiones http.
Hola Javi, Eso se debe a que live-server tiene una característica de live-reload que cada que detecta un cambio se actualiza. Es probable que el servidor http que se configuró no tenga esa funcionalidad.
se olvido de dejar el codigo para poder amalizarlo mejor
Tengo aun este error, ya trate de debuggear pero no encontre como solucionarlo, compañeros en esta clase llegaron a tener el mismo problema, uso VS con Live Server
router.js:14 Uncaught TypeError: Cannot read property 'template' of undefined at Route.loadRoute (router.js:14) at Route._loadInitialRoute (router.js:36) at new Route (router.js:4) at index.js:1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Curso/Taller SPA</title> </head> <body> <header> <ul> <li><Button onclick="router.loadRoute('')">Home</Button></li> <li><Button onclick="router.loadRoute('contact')">Contacto</Button></li> <li><Button onclick="router.loadRoute('about')">Acerca de mi</Button></li> </ul> </header> <div data-router> <!-- Builder --> </div> <script src="router.js"></script> <script src="routes.js"></script> <script src="index.js"></script> </body> </html>
const routes = [ { path: '/', template: '<h1>Hola</h1>' }, { path: '/contact', template: '<h1>Contacto</h1>' }, { path: '/about', template: '<h1>Acerca de mi</h1>' }, { path: '/index.html', template: '<h1>Home</h1>' } ];
class Route { constructor(routes) { this.routes = routes; this._loadInitialRoute(); } loadRoute(...urlSegs) { const matchedRoute = this._matchUrlToRoute(urlSegs); // debugger const url = `/${urlSegs.join('/')}`; history.pushState({}, 'This works', url); // debugger const routerOutElm = document.querySelectorAll('[data-router]')[0]; routerOutElm.innerHTML = matchedRoute.template; } _matchUrlToRoute(urlSegs) { const matchedRoute = this.routes.find(route => { const routePathSegs = route.path.split('/').slice(0); // debugger if (routePathSegs.length !== urlSegs.length) { // debugger return false; } // debugger return routePathSegs .every((routePathSeg, i) => routePathSeg === urlSegs[i]) }); if (matchedRoute === undefined) { return { template: '<h1>Not found</h1>' }; } return matchedRoute; } _loadInitialRoute() { const pathNameSplit = window.location.pathname.split('/'); const pathSegs = pathNameSplit.length > 1 ? pathNameSplit.slice(1) : ''; this.loadRoute(...pathSegs) } }
const router = new Route(routes);
Trate de arreglarlo con una validacion sugerida, sin embargo NO funciona
Probe el código y me funciona correctamente, pero te dejo el mio puede que te funcione y te aclare ciertas dudas
Path.js
const PATHS = { home: { path: "/", template: "<h1>Home 🏠</h1>", }, about: { path: "/about", template: "<h1>Sobre mi 👨🏻💻</h1>", }, contact: { path: "/contact", template: "<h1>Contacto 📲</h1>", }, error: { path: "/", template: "<h1>Error ⛔️</h1>", }, }
Router.js
class Router { /** * Metodo inicial. * * @return {void}. */ constructor(paths) { this.paths = paths; this.initRouter(); } /** * Permite inicializar el router * * @return {void}. */ initRouter() { const { location: { pathname = "/" } } = window; const URI = pathname === "/" ? "home" : pathname.replace("/", ""); this.load(URI); } /** * Permite iniciar la carga de paginas. * * @return {void}. */ load(page = "home") { const { paths } = this; const { path, template } = paths[page] || paths.error; const $CONTAINER = document.querySelector("#content"); $CONTAINER.innerHTML = template; window.history.pushState({ }, "Genial", path); } } const ROUTER = new Router(PATHS);
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Manejo de Routers</title> </head> <body> <header> <nav> <ul> <li> <button id="Home" onclick="ROUTER.load('home')">Home</button> </li> <li> <button id="About" onclick="ROUTER.load('about')">About</button> </li> <li> <button id="Contact" onclick="ROUTER.load('contact')">Contact</button> </li> </ul> </nav> </header> <section> <div id="content"> </div> </section> <footer></footer> <script src="./Paths.js"></script> <script src="./Router.js"></script> </body> </html>
Hola compañero, tenia el mismo problema, y el tema esta en el uso del live server, ya que la ventana que abre el live server genera una url diferente a la que se genera con un servidor como el que genera el profesor, haciendo que en la función _loadInitialRoute la constante pathSegs sea igual a ["index.html"], creando un error.
Si creas el servidor con npm como lo hace el profesor o lo abres con un programa que te genera este servidor automáticamente (yo use prepos), ya vas a ver que funciona normal. Espero te ayude.
Saludos!