0

I am in the process of learning Typescript and am converting my React project to TS. However, I've hit a bit of a roadblock and I'm not quite sure what to do with this file:

import { Grid } from '@material-ui/core';
import { useParams } from 'react-router-dom';
// @ts-ignore
import ProductImage from './ProductImage.tsx';
// @ts-ignore
import ProductInfo from './ProductInfo.tsx';

type Props = {
  products: {
    id: number;
    price: number;
    description: string;
    listing_type: string;
    image: string;
  }[];
  addToCart: (e: MouseEvent) => void;
  user: {
    id: number;
    isAuth: boolean;
  };
}

const Product: React.FC<Props> = ({ products, addToCart, user }) => {
  const { productId } = useParams<{productId: string}>()

  const product = products.find(product => product.id === parseInt(productId));

  return (
    <div>
      <Grid container spacing={1} style={{ maxWidth: 1100, margin: '0 auto', marginTop: '5rem' }}>
        <Grid item sm={4}>
          <ProductImage image={product?.image} />
        </Grid>
        <Grid item sm={8}>
          <ProductInfo product={product} onClick={(e: React.MouseEvent<Element, globalThis.MouseEvent>) => addToCart(e)} user={user}/>
        </Grid>
      </Grid>
    </div>
  );
}

export default Product;

I added the @ts-ignore lines because of errors related to importing files ending with .tsx. However, now when I try to run npm start, I get the following error:

TypeError: products.find is not a function
Product
src/components/products/ProductShow.tsx:27
  24 | const Product: React.FC<Props> = ({ products, addToCart, user }) => {
  25 |   const { productId } = useParams<{productId: string}>()
  26 |   console.log(products)
> 27 |   const product = products.find(product => product.id === parseInt(productId));
  28 | 
  29 |   return (
  30 |     <div>

(I should note that products are passed down as an array of objects from a higher component)

At this point, I'm not sure if I'm defining my prop types incorrectly or if there is another issue with how I've set everything up. Any help with either configuring my project so that .tsx files can be imported or defining my prop types correctly would be greatly appreciated!

Here is my tsconfig.json file

{
  "compilerOptions": {
    "target": "es2016",
    "module": "esnext",
    "noImplicitAny": true,
    "esModuleInterop": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "strict": true,
    "jsx": "react-jsx",
    "allowJs": true,
    "checkJs": false,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": [
    "src"
  ]
}
12
  • This could just be that your array of products is not defined on the initial render Commented Nov 29, 2021 at 16:59
  • What is the initial value of products that are passed down as props? Commented Nov 29, 2021 at 17:04
  • The array of products is in the Redux store which is what is passed to this component. Also, this is a product show page, so I'm using params to determine the id of the product to display. Commented Nov 29, 2021 at 17:08
  • Using console.log, this is the array of products before the error hits: {products: Array(20), loading: false} loading: false products: (20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] [[Prototype]]: Object Commented Nov 29, 2021 at 17:10
  • Each object contains the correct info - id, price, description, etc Commented Nov 29, 2021 at 17:11

1 Answer 1

1

The console log shared in the comments explains this issue. products is logging as:

{products: Array(20), loading: false}

.find() exists on Array.prototype, but is being called on an object. The prop products should be passed as the array of products, rather than an object.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.