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 33

Preguntas 6

Ordenar por:

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

o inicia sesión.

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>

Les comparto mi resultado del reto:

 
Aquí pueden ver todo el código:
Repositorio en GitHub

Que risa jajajajjajaja

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>

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

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

Así está quedando My Orders y Order detail


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!

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];

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

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/>} 
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}
          />
        ))}

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}
     />
))}

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

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)

Cualquier parecido es mera coincidencia 👀

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}
            />
            ))
          }

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

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)) ```