0

So i'm currently making a receipt for my POS app.

I currently have stored an array in my database as: mongodb collection

And I want to map them to a receipt page

function renderTable(orderlist) {
    return (
      <tr className='service'>
        <td className='tableitem'>
          <p className='itemtext'>{orderlist.name}</p>
        </td>
        <td className='tableitem'>
          <p className='itemtext'>{orderlist.qty}</p>
        </td>
        <td className='tableitem'>
          <p className='itemtext'>{orderlist.subtotal}</p>
        </td>
      </tr>
    );
  }



const showReceipt = ({
    values,
    errors,
    touched,
    handleChange,
    handleSubmit,
    isSubmitting,
  }) => {
    return (
      <div id='bot'>
        <div id='table'>
          <table>
            <tbody>
              <tr className='tabletitle'>
                <td className='item'>
                  <h2>Item</h2>
                </td>
                <td className='Hours'>
                  <h2>Qty</h2>
                </td>
              </tr>
              {values.order_list.map((orders) => {
                renderTable(orders.order_list);
              })}
              <tr className='tabletitle'>
                <td />
                <td className='Rate'>
                  <h2>tax</h2>
                </td>
                <td className='payment'>
                  <h2>$419.25</h2>
                </td>
              </tr>
              <tr className='tabletitle'>
                <td />
                <td className='Rate'>
                  <h2>Total</h2>
                </td>
                <td className='payment'>
                  <h2>{values.total}</h2>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div id='legalcopy'>
          {/* <p className='legal'>
            <strong>Thank you for your business!</strong>&nbsp; Payment is
            expected within 31 days; please process this invoice within that
            time. There will be a 5% interest charge per month on late invoices.
          </p> */}
        </div>
      </div>
    );

And it is currently showing me this error:

TypeError: Cannot read property 'map' of undefined

I can't for some reason map this one particular object.

I can, however, Return them as string with : JSON.Stringify(orderlist)

I can also log the object in console

For whatever reason I just can't map them. I want the function to return a row for each Order_list content

2 Answers2

0

99% of the time with these problems, your values are available at some point, but since you are getting them from an api and that takes time, not during your first render. Before mapping over it, check if values is alreaady set and otherwise show a loading indicator.

phry
  • 35,762
  • 5
  • 67
  • 81
  • You might be right, I tried to map just the `values`, and it also returns `undefined` although I wonder why returning the `values.total` works just fine, whereas mapping `values.order_list` returns `undefined`. Is it because mapping takes more time? if so, what can I do to map `values.order_list`? edit: mapping just the `values` actually returns `map is not a function` – Aqiel Ilhamy Jul 15 '21 at 09:03
0

When you call api. The values.order_list is a initial value you defined on the reducer. So if you don't defined the initial of order_list, values.order_list is undefined. You can use optional chaining to check before call map like this.

values.order_list?.map
Viet
  • 12,133
  • 2
  • 15
  • 21
  • Thanks! checking before the mapping with `values.order_list?.map` doesn't return anything with no errors. How do I tell it to wait until `values.order_list` have value in it, then execute the mapping? – Aqiel Ilhamy Jul 15 '21 at 09:35