Home > Blockchain >  I have an error trying to fetch data from database to frontend using GET method
I have an error trying to fetch data from database to frontend using GET method

Time:05-22

Compiled with problems:X

ERROR

src\component\Products.jsx Line 8:34: React Hook "useState" is called in function "getAllProducts" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use" react-hooks/rules-of-hooks

I'm trying to use useState, what is the best way to fetch the data from database to frontend

import React, { useState } from 'react';
import { NavLink } from 'react-router-dom';
import DATA from '../Data';


const getAllProducts = () => {

    const [products, getproducts] = useState({
        title : '',
        price : '',
        image : ''
    });

    const {title, price, image}=  products;
     let getproduct = fetch('http://localhost:6000/products/allProducts', {
        method : 'GET',
        headers : {
            'Content-Type':'application/json'
        },
        body : JSON.stringify({
            title, price, image
        })
    
})

    const cardItem = (item) => {
        return(

            
            <div className="card mx-3 my-5 py-3 px-2" key={item.id} style={{width: "15rem"}} id="cards">
                        <img src={item.image} className="card-img-top" alt={item.title} />
                        <div className="card-body text-center">
                            <h5 className="card-title fw-bolder" id="para">{item.title}</h5>
                            <p className="lead fw-bold" id="para">${item.price}</p>
                            <NavLink to={`products/${item.id}`} className="btn btn-outline-danger fw-bolder px-5 rounded-pill" id="para">Buy Now</NavLink>
    
                        </div>
                    </div>      
            );
    }

    return (
        <div>
            <div className="container py-2 mt-5 pt-5">
                <div className="row">
                    <div className="col-12 text-center">
                        <h1 className="display-6 fw-bolder text-center" id="late">Latest Collections</h1>

                        <hr/>
                    </div>
                </div>
            </div>
            <div className="container" id="products">
                <div className="row justify-content-around">
                    {getproduct.map(cardItem)}
                </div>
            </div>
        </div>
        );

}

export default getAllProducts;

CodePudding user response:

Hi

First I notify you of errors in your code and then expose you a solution:

In getAllProducts you use a useState but you can't use it this way, it's not a React component.

You also call getAllProducts.map but getAllProducts doesn't return any data array

In your useState the initial value represents ONLY one object of your data array


I would advise you this one , it's near of what you have done.

We create a method to get the data, a state to store the data and we display them conditionally

In my example below I use the axios library, it is an alternative to the fetch method that you use but the principle remains the same with the fetch method (except for one line of code)

I hope it helps you

import React , {useState,useEffect} from 'react'
import axios from 'axios'

const getAllProducts = async ()=>{
//Here is the fetch method
try{
 const fetchQuery = await axios.get('my-url')
return fetchQuery.data

}
catch(error){
    console.log(error)
}}



const CardItem = (props)=>(
  //here you card component that will be mapped
  <div>
    <p>{props.data.title}</p>
    <p>{props.data.price}</p>
  </div>
  )

const MappedCards = ()=>{
    //Our initial state is a empty array
  const [allProducts,setProducts] = useState([])
  
    
  useEffect(()=>{
  // I use the hook useEffect so when the MappedCards component is mounted
  // I can fetch data and use the setProducts method
    
    const initProducts = async ()=>{
      const data = await getAllProducts()
      setProducts(data)
    }
    
    //I call the method to initProducts
    initProducts()
    
  },[])
  
  
  // I can even make something really cool here

  if(allProducts.length === 0){
   return <span>Loading data...</span> 
  }

  // Now when allProducts will be filled with data I'll show this
  
  return (<div className="my-container">
  <h1>My shop</h1>
  {allProducts.map(product => (<CardItem key={product.id} data={product} />}
  </div>)
  
}
  

export MappedCards

CodePudding user response:

thanks for helping but im still getting this error: Uncaught TypeError: Cannot read properties of undefined (reading 'map')

Here is the code with the code that you suggested.

My goal is to fetch the data successfully from the database to the front end:

import React, { useState, useEffect }from 'react';
// import DATA from '../../Data';
import { NavLink } from 'react-router-dom';
import axios from 'axios';



const Inventory = () => {

    const [allProducts,setProducts] = useState([])
      
        

    const getAllProducts = async ()=>{
    //Here is the fetch method
    try{
     const fetchQuery = await axios.get('http://localhost:6000/products/allProducts')
    return fetchQuery.data

    }
    catch(error){
        console.log(error)
    }}

    useEffect(()=>{
    // I use the hook useEffect so when the MappedCards component is mounted
    // I can fetch data and use the setProducts method
      
      const initProducts = async ()=>{
        const data = await getAllProducts()
        setProducts(data)
      }
      
      //I call the method to initProducts
      initProducts()
      
    },[])




    const Table = (items) => {
        return (
            <div className="table-responsive">
              <table className="table table-striped table-sm">
                <thead>
                  <tr>
                    <th scope="col">id#</th>
                    <th scope="col">image</th>
                    <th scope="col">stocks</th>
                    <th scope="col">name</th>
                    <th scope="col">price</th>
                    <th scope="col">description</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td>{items.id}</td>
                    <td><img src={items.image} alt="" height="200px" width="300px" /></td>
                    <td>{items.stocks}</td>
                    <td>{items.title}</td>
                    <td>{items.price}</td>
                    <td>{items.desc}</td>
                  </tr>       
                </tbody>
              </table>
            </div>

            )
    }

    return (
    <div>
            <div className="container-fluid mt-5 pt-5">
              <div className="row">
                <nav id="sidebarMenu" className="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
                  <div className="position-sticky pt-3">
                    <ul className="nav flex-column">
                      <li className="nav-item">
                        <NavLink className="nav-link active" aria-current="page" to="/dashboard">
                          <i className="fa fa-home me-2"></i>
                          Dashboard
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to='/all'>
                          <i className="fa fa-file-o me-2"></i>
                           All Products
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to='/addProduct'>
                          <i className="fa fa-cart-arrow-down me-2"></i>
                           Add Product
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="/orders">
                          <i className="fa fa-cart-arrow-down me-2"></i>
                          Orders
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-users me-2"></i>
                          Customers
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-list-ul me-2"></i>
                          Reports
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-database me-2"></i>
                          Integrations
                        </NavLink>
                      </li>
                    </ul>

                    <h6 className="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
                      <span>Saved reports</span>
                      <NavLink className="link-secondary" to="#" aria-label="Add a new report">
                        <i className="fa fa-plus-square me-2"></i>
                      </NavLink>
                    </h6>
                    <ul className="nav flex-column mb-2">
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-calendar me-2"></i>
                          Current month
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-calendar-check-o me-2"></i>
                          Last quarter
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-comments me-2"></i>
                          Social engagement
                        </NavLink>
                      </li>
                      <li className="nav-item">
                        <NavLink className="nav-link" to="#">
                          <i className="fa fa-bar-chart me-2"></i>
                          Year-end sale
                        </NavLink>
                      </li>
                    </ul>
                  </div>
                </nav>

                <main className="col-md-9 ms-sm-auto col-lg-10 px-md-4">
                  <div className="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
                    <h1 className="h2">Dashboard</h1>
                    <div className="btn-toolbar mb-2 mb-md-0">
                      <div className="btn-group me-2">
                        <button type="button" className="btn btn-sm btn-outline-secondary">Share</button>
                        <button type="button" className="btn btn-sm btn-outline-secondary">Export</button>
                      </div>
                      <button type="button" className="btn btn-sm btn-outline-secondary dropdown-toggle">
                        <span data-feather="calendar"></span>
                        This week
                      </button>
                    </div>
                  </div>

                  <h2>Products</h2>
                  {allProducts.map(product => (<Table key={product.id} data={product} />))}
                </main>
              </div>
            </div>
        </div>
        );
}


export default Inventory;
  • Related