skip to Main Content

After gaining some experience in back-end development, I got bored to create beautiful things and not seeing them, so i decided to move towards front-end, with concrete thoughts that it is easy=)

And here is my first problem…
Product Id is not coming into my axios REST api, so the Product can’t be rendered,because back-end can’t send JSON

Also when i try to hit the button that Links into my Product component, this happens

to load resource: the server responded with a status of 400 ()
 http://localhost:8080/product/undefined

Product component

import React, { useState, useEffect } from 'react';
import { useParams } from "react-router-dom";
import axios from 'axios';

const Product = () =>{
  const [items,setItems] = useState([]);
  const {id} = useParams();

useEffect(() => {
  fetchItems();
}, []); 

const fetchItems = () => {
    axios
        .get(
          `http://localhost:8080/product/${id}`
        )
        .then((res) => {
            setItems(res.data);
            console.log(res.product);
        })
        .catch((err) => {
          console.log(err)
        });
};
  return (
    <div>
      {items.map((item) =>(
          <div className='product-container' key={item.id}>
            <div>
              <img className='prod-image' src={item.imageURL} alt='' />
            </div>
            <div>
              <h2>{item.name}</h2>
              <p>{item.description}</p>
              <p>
                <strong>Price:</strong> {item.price}
              </p>
            </div>
          </div>
      ))}
    </div>
  );
};
export default Product;

Home component that lists all Products

import React,{useState,useEffect} from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

const Home = () => {
  const [products, setProducts] = useState([]);

useEffect(() => {
  fetchProducts();
}, []);

const fetchProducts = () => {
  axios
    .get('http://localhost:8080/product/')
    .then((res) => {
      console.log(res);
      setProducts(res.data);
    })
    .catch((err) => {
      console.log(err);
    });
};

  return (
    <div>
      <h1>Наша продукция</h1>
      <div className='item-container'>
        {products.map((product) => (
          <div className='card' key={product.id}>
            <img src={product.imageURL} alt='' />
            <h3>{product.name}</h3>
            <p>{product.description}</p>
            <a>{product.price} ₽</a>
              <Link to={`/product/${product.id}`}>View</Link>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Home;
i am getting this error 
items.map is not a function
TypeError: items.map is not a function
    at Product (http://localhost:3000/static/js/bundle.js:1085:67)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:26207:22)
    at updateFunctionComponent (http://localhost:3000/static/js/bundle.js:29089:24)
    at beginWork (http://localhost:3000/static/js/bundle.js:30801:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:15799:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:15843:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:15900:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:35774:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:35021:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:34944:9)

3

Answers


  1. Chosen as BEST ANSWER

    Solved it, The problem was because Product comes as json object where i was trying to render it like an array and in this case i get error because there i nothing to iterate over.

    {
      "id": 1,
      "name": "Lipstick",
      "imageURL": "imagesForProject/lipsick.png",
      "price": 1100,
      "description": "description to the product ",
      "categoryId": 1
    }
    

    Here is the right answer

    import React, { useState, useEffect } from 'react';
    import { useParams } from "react-router-dom";
    import axios from 'axios';
    
    const Product = () =>{
      const [item,setItem] = useState([]);
      const {id} = useParams();
    
    useEffect(() => {
      fetchItem();
    }, []); 
    
    const fetchItem = () => {
        axios
            .get(
              `http://localhost:8080/product/${id}`
            )
            .then((res) => {
                setItem(res.data);
                console.log(res.product);
            })
            .catch((err) => {
              console.log(err)
            });
    };
      return (
        <div>
              <div className='product-container' key={item.id}>
                <div>
                  <img className='prod-image' src={item.imageURL} alt=''/>
                </div>
                <div>
                  <h2>{item.name}</h2>
                  <p>{item.description}</p>
                  <p>
                    <strong>Price:</strong> {item.price}
                  </p>
                </div>
              </div>
        </div>
      );
    };
    export default Product;
    

  2. Typo mistake. You can use useParams as a function.

    const {id} = useParams();
    
    Login or Signup to reply.
  3. before fetch request item is empty or null so you need set to optional variable , It is telling the Compiler if item exist then do mapping
    see code bellow

    items.map to items?.map
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search