No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Página de MyOrder: órden individual

24/31
Recursos

Aportes 44

Preguntas 7

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Para esta clase use useParams de react-router-dom:

MyOrder/index.js

import {  useParams } from "react-router-dom";

Dentro de la función de MyOrder:

const params = useParams();
  const indexOrderPath = Number(params.id);

para el caso en el que nos encontremos en la ruta “/my-orders/last”, indexOrderPath tendrá el valor de NaN.
En el otro caso en donde nos encontremos en la ruta “/my-orders/0” , por ejemplo, indexOrderPath tendrá el valor de 0.
Pero ese problemita lo resolví de la siguiente manera:

<div className="flex flex-col w-80">
          {!isNaN(indexOrderPath) && context.order?.[indexOrderPath].products.map((product) => (
            <OrderCard
              key={product.id}
              id={product.id}
              title={product.title}
              img={product.images[0]} 
              price={product.price}
            />
          ))}
          {isNaN(indexOrderPath) && context.order?.slice(-1)[0].products.map((product) => (
            <OrderCard
              key={product.id}
              id={product.id}
              title={product.title}
              img={product.images[0]} 
              price={product.price}
            />
          ))}
        </div>

Le agregué el total al pedido 😉:



En: MyOrder:

<div className='flex w-80 mt-4'>
        <p className='flex w-full items-center justify-between'>
          <span className='font-normal text-xl'>Total: </span>
          <span className='font-medium text-2xl pr-2'>${context.order?.[index]?.totalPrice}</span>
        </p>
      </div>

Yo mostre en la misma pagina el historial de ordenes y el detalle de cada orden

Estuvo medio confusa la solución de esta clase, no creo que sea la mejor pero ok, no me dio error al final.

Hello guys, I want to give you a little advice here. Using the element index of an array with objects as an id is a very bad practice, due to a lack of stability and data integrity, especially when the lists change dynamically. Try to use something else, such as the uui library which you can simply install by putting

npm install uuid

in the command prompt, this will generate a random string with both characters and numbers that will serve the purpose of an id. Hope this is useful!

Ya se me pegó la forma de celebrar de Teff cuando todo sale bien. Diciendo: “Jeiii!!!”

Creo que usando useParams y una mejor organización en el funcionamiento se hubiera resuelto mucho mejor.

Otra forma usando javascript puro sería hacerle un split al pathname enviando el slash ‘/’ como argumento y luego obetener la última posición de ese array, por lo general siempre lo hago así.

  const pathSplitted = window.location.pathname.split('/');
  const orderId = pathSplitted[pathSplitted.length - 1];

Cualquier parecido es mera coincidencia 👀

Yo lo resolví instalando UUID para asignarle un ID a cada orden.
Luego en MyOrder/index.js utilice el hook useParams de React Router

import { useParams } from "react-router-dom"; 

Dentro de la función MyOrder obtengo el parametro id con destructuración y chequeo para obtener la orden a mostrar. Si el parametro es ‘last’ llega como undefined, entonces hago el slice, sino con el id uso el filter

let orderToShow = id === undefined ? order?.slice(-1)[0] : order?.filter(order => order.id === id)[0] 

Y por último, en el div recorro los productos de orderToShow con map para mostrar las OrderCard

{orderToShow?.products.map((item) => (
    <OrderCard
         key={item.id}
         id={item.id}
         title={item.title}
         image={item.image}
         price={item.price}
     />
))}

Yo lo resolví de la siguiente manera

en el contexto:

//cree un variable que me diga el index de la orden a mostrar
const [orderToShow, setOrderToShow] = useState(Number) 

en Myorders:

//cree una función que cuando de click a la orden actualice la variable de ordenToshow guardando su inde

 const showOrder=(index)=>{
  setOrderToShow(index)
 }

en Myorder:

//cambio el slice por el numero de index que quiero mostrar

{order[orderToShow]?.products.map(item => <OrderItem item = {item} key = {item.id}/>)} 

nota: para esto tambien deben mandar el index que quieren ver cuando le den a checkout:

//agrego al final un llamado a la funcion con el index order.length para ver la ultima orden 
  const handleCheckout= ()=>{
    const orderToAdd ={
      date: new Date,
      products: cartProducts,
      totalProducts: cartProducts.length,
      totalPrice: totalPrice(cartProducts)
    }
    setOrder([...order, orderToAdd])
    setCartProducts([])
    setOrderToShow(order.length)
  }

y en la ruta pongo que todas las rutas /myorder/* lleven a myOrder

{path:'/myorder/*', element:<MyOrder/>} 
Individual order:![](https://static.platzi.com/media/user_upload/image-64d1b4f2-d507-4008-aee5-2567a90fc146.jpg) My Orders:![](https://static.platzi.com/media/user_upload/image-349342e0-210c-432f-9291-40c3768a0cf5.jpg)

¡Después de estudiar todo el día en platzi, ya se puso raro…!

Asi va quedando ![](https://static.platzi.com/media/user_upload/image-7aeaa671-e7fe-43be-9914-3a770840e9e0.jpg)
10:23 la risa 😈

en lo person preferí en lugar de usar el index, generar un UUID, lo hice con esta lib https://github.com/uuidjs/uuid#readme

para los que se aventuraron a hacer el curso con Nextjs y app router (como yo) solo hay que ponerle corchetes [] al nombre de la carpeta para hacerlo una ruta dinamica (amo ❤️ !)

Esta fue mi solución que opina?
primero para obtener el path y el id de las ordenes desde la url

  const params = useParams();
  const pathName = window.location.pathname


luego coloque la condición al momento del render si es /last muetre el -1, si no el id de la url y ya.

{order?.slice((pathName ==='/my-orders/last') ? -1 : params.id  ) [ 0 ].products.map(product => (
          <OrderCard
            key={product.id}
            id={product.id}
            title={product.title}
            image={product.image}
            price={product.price}
          />
        ))}
## ✨🦄Así como algunos comentarios mencionaron, utilicé uuid para asignar ids únicos a las órdenes. Y mi vista de Orders quedó así: ![](https://static.platzi.com/media/user_upload/image-a2f62d52-dd0e-40a2-b537-2d222be0e058.jpg) Mientras que utilicé useParams de react-router-dom para enviar como parámetro el id de la orden a la vista de MyOrder. Esta es la nueva ruta que se tuvo que agregar a las rutas que estan en App ![](https://static.platzi.com/media/user_upload/image-529a1cfd-5bcf-442e-962b-469d19a46af5.jpg) Así me quedó el MyOrder :3 ![](https://static.platzi.com/media/user_upload/image-dd71453c-7f55-4ada-a9e0-2780b14c46ea.jpg)
Lo mejor es usar el Hook de useParams, pero aqui les dejo otro metodo para traer el id de route usando split(): ```js   const currentPath = window.location.pathname.split('/')  const index = currentPath[currentPath.length - 1] ```
Lo mejor es usar el Hook de useParams, pero aqui les dejo otro metodo para traer el id de route usando split(): `  const currentPath = window.location.pathname.split('/')  const index = currentPath[currentPath.length - 1]`
ESPERO A ALGUIEN LE SIRVA ESTO: Por alguna razón me agregaban digitos a mi url de esta forma: /my-orders/0%7D Así que veia las ordenes totales o cada orden por separado Lo que hice fue crear un indexId que lo que hace es tomar el primer caracter de mi index original y quitar lo que no va que es: %7D `let indexId = index.substring(0,1)` Despues solo hago la comparación del primer digito de "last" osea la "l" `if(indexId === "l") indexId = context.order?.length - 1` Por ultimo lo sustitui en la OrderCard: `context.order?.[indexId]?.products.map(`...\*aquí va el demas codigo para la card..\* ![](https://static.platzi.com/media/user_upload/image-48059981-23be-4018-8ec2-7e706362ffde.jpg)
ReferenceError: id is not defined
```js import { useContext } from 'react' import { ShoppingCartContext } from '../../Context' import Layout from '../../Components/Layout' import OrderCard from '../../Components/OrderCard' import { ChevronLeftIcon } from '@heroicons/react/24/solid' import { Link, useLocation } from 'react-router-dom' import { Product } from '../../lib/definitions' function MyOrder() { const {order} = useContext(ShoppingCartContext); const location = useLocation(); const searchParams = new URLSearchParams(location.search); const id = searchParams.get('id'); // Busca la orden correspondiente al ID const orderById = order.find(o => o.id === id); return ( <Layout>
<Link to='/my-orders' className='absolute left-0'> <ChevronLeftIcon className='h-6 w-6 text-black cursor-pointer' /> </Link>

My Order

{ orderById?.products.map((product: Product) => ( <OrderCard key={product.id} {...product} /> )) }
</Layout> ) } export default MyOrder ```import { useContext } from 'react'import { ShoppingCartContext } from '../../Context'import Layout from '../../Components/Layout'import OrderCard from '../../Components/OrderCard'import { ChevronLeftIcon } from '@heroicons/react/24/solid'import { Link, useLocation } from 'react-router-dom'import { Product } from '../../lib/definitions' function MyOrder() {  const {order} = useContext(ShoppingCartContext);    const location = useLocation();  const searchParams = new URLSearchParams(location.search);  const id = searchParams.get('id');   // Busca la orden correspondiente al ID  const orderById = order.find(o => o.id === id);   return (    \<Layout>      \
        \<Link to='/my-orders' className='absolute left-0'>          \<ChevronLeftIcon className='h-6 w-6 text-black cursor-pointer' />        \</Link>        \

My Order\

      \
      \
        {          orderById?.products.map((product: Product) => (            \<OrderCard              key={product.id}              {...product}            />          ))        }      \
    \</Layout>  )} export default MyOrder
Claramente en esta clase ya se está empezando a "simular" la parte de la que debería encargarse el backend, pero creo que hubiese sido más rápido para identificar la parte final de la url un simple: ```js const indexFromUrl = currentPath.split("/").at(-1); ```Y como adicional, si fuese por algún (no recomendado) motivo a utilizarse este método efectivamente en algún punto, sería importante hacer una validación para asegurarse que la respuesta siempre sea un índice y no nos devuelva 'my-orders'.
En lo personal me encanta tomar clases aquí, uno siempre descubre nuevas formas de hacer las cosas!
otra solución seria dividir la cadena del texto nos retornaría un array y dicho array tomamos la parte que necesitamos ```js const currectPath = window.location.pathname.split('/')[2] console.log(currectPath) ```
La otra forma es generar un id random con       *   id: crypto.randomUUID() code ```js const orderToAdd = { date: "01.02.23", products: cartProducts, totalProducts: cartProducts.length, totalPrice: totalPriceProducts, id: crypto.randomUUID() }; ```     
`const currentPath = window.location.pathname ` `const orderId = currentPath.split('/').slice(-1)[0]`
`onst currentPath = window.location.pathname const orderId = currentPath.split('/').slice(-1)[0]`
```js export const  useCurrentOrderFromUrl = () => {  const context = useContext(ShoppingCartContext);  const { pathname } = useLocation();  const { id } = useParams();   const orderId = pathname === '/my-orders/last' ? context.order\[context.order.length - 1]?.id : parseInt(id);    return context.order.find((order) => order.id === orderId);}; ```
la parte del index la hice mejor con ternary operator: ```js const index = currentPath.substring(currentPath.lastIndexOf('/') + 1) === 'last' ? order?.length - 1 : currentPath.substring(currentPath.lastIndexOf('/') + 1) ```const index =    currentPath.substring(currentPath.lastIndexOf('/') + 1) === 'last' ? order?.length - 1 : currentPath.substring(currentPath.lastIndexOf('/') + 1)
Así me quedó a mi : ![](https://static.platzi.com/media/user_upload/image-e9a34009-23d4-46f6-ba29-6a51573400b3.jpg)

Reto cumplido:

jejeje Ahora si!

Así le hice el diseño.

Algo que lejos de considerar una mala práctica el uso de let e if en un componente puede convertirse en un problema de deuda técnica, pongo como lo resolví con useState y useEffect, garantizando la estabilidad del componente

import { useContext, useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { ChevronLeftIcon } from "@heroicons/react/24/solid";
import { Layout } from "../../Components/Layout";
import { OrderCard } from "../../Components/OrderCard";
import { ShoppingCartContext } from "../../Context";

export const MyOrder = () => {
  const context = useContext(ShoppingCartContext);
  const currentPath = window.location.pathname;

  const [index, setIndex] = useState(
    currentPath.substring(currentPath.lastIndexOf("/") + 1)
  );
  useEffect(() => {
    if (index === "last") setIndex(context.order?.length - 1);
  }, []);

  return (
    <Layout>
      <div className="flex items-center justify-center w-80 relative mb-6">
        <Link to="/my-orders" className="absolute left-0">
          <ChevronLeftIcon className="h-6 w-6 black cursor-pointer" />
        </Link>
        <h1>My Order</h1>
      </div>
      <div className="flex flex-col w-80">
        {context.order?.[index]?.products.map((product) => (
          <OrderCard
            id={product.id}
            key={product.id}
            title={product.title}
            imageUrl={product.images}
            price={product.price}
          />
        ))}
      </div>
    </Layout>
  );
};

jejeje me confundi un poco en esta clase pero la entendí

Que es lo significa el signo de pregunta ?

Creo que podemos resolver esta parte del proyecto con algo más simple.

  1. Declaré una variable fuera de la función, el cual será el responsable de tomar un valor a partir de una condicional ternaria.
  2. Creo una variable dentro del componente que siempre obtendrá el último valor del array. Así mismo, uso flat() para aplanar el array para poder desestructurar en el return.
  3. Usé el hook useResolvedPath() agregando su propiedad .pathname para obtener la url, también uso el método split('/') para separar la cadena. Aquí también uso desestructuración
  4. Hago la ternaria para asignar como valor de productList un array u otro.
let productsLits

function MyOrder () {
  const lastOrder = order.slice(order.length - 1).flat()
  const [domain, currentPage, productIndex] = useResolvedPath().pathname.split('/')

  productsLits = (productIndex === 'last') ? lastOrder : order[productIndex]

  return (
    ...
        {
          productsLits.map(({ image, title, price }) => (
            <CartItem
              key={title}
              image={image}
              title={title}
              price={price}
            />
          ))
        }
    ...
  )
}

Yo lo hice de la siguiente manera.

  const pathSplitted = window.location.pathname.split('/');
  let param = pathSplitted[pathSplitted.length - 1];
  let result

  if (param === "last") {
    result = context.order.slice(-1)[0]
  } else {
    result = context.order.slice(param)[0]
  }
          {
          result.products.map(product => (
            <OrderCard 
              key={product.id}
              id={product.id}
              title={product.title} 
              imagesUrl={product.images} 
              price={product.price}
              quantity={product.quantity}
            />
            ))
          }

Asi me quedaron mis ordenes 😃

en mi caso también use el hook de useParams, de la siguiente manera. Lo primero que hice fue agregar la ruta correspondiente en mi aplicación: ```js <Route path='/my-order' element={ <MyOrder />}/> <Route path='/my-order/:id' element={ <MyOrder />}/> ```De esta manera cualquier cosa que ponga luego del slash me lo manda como parámetro. En el elemento de MyOrder obtengo el id con el hook de useParams() ```js const params = useParams() const id = params.id ```De esta manera en mi componente leo cualquier cosa que haya después del slash, en mi caso sería un número aleatorio de 7 cifras o la palabra 'last'. También hay que tener en cuenta que el hook me da los parámetros como un string. Por último, según lo que tenga como id obtengo la información de la orden desde el contexto. ```js const order = id === 'last' ? orders.slice(-1)[0] : orders.find( item => item.orderNumber === parseInt(id)) ```