Search code examples
phpreactjspdowebpack-2fetch-api

fetch() data from database and set as React.js component state


Trying for the love of god to fetch data from my database and put into my React Component state, but cant understand what I'm doing wrong. This is my PHP file:

<?php

  $servername = "localhost";
  $username = "root";
  $password = "root";
  $dbname = "maggan";

  // Create connection
  $conn = new mysqli($servername, $username, $password, $dbname);

  // Check connection
  if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
  }

  $sql = "SELECT * FROM Items";
  $result = $conn->query($sql);
  while($row = mysqli_fetch_assoc($result))
  $items[] = $row;
  echo json_encode($items);

  $conn->close();

?>

and this is my React component:

import React, { Component } from 'react';

// Component import
import Menu from './components/menu';
import Footer from './components/footer';
import ProductContainer from './components/productContainer';
import CategoryContainer from './components/categoryContainer';

class Archive extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      products: [],
      category: ""
    }
    this.filterHandler = this.filterHandler.bind(this);
  }

  // Set component state to the currently clicked "cat" (CategoryItem)
  filterHandler(tag){
    this.setState({
      category: tag
    })
  }

  componentDidMount(){
    fetch("/getProducts", {
      method: "GET",
      headers: {
        "Content-Type": "application/json"
      }
    })
    .then(async res => {
      const data = await res.json();
      setState({
        products: data
      })
    })
    .catch(function(err) {
      console.log('ERROR!!! ' + err.message);
    });
  }

  render() {
    // 1. Render CategoryContainer with props products and filterHandler function to show all uniqe CategoryItems and filter products based on category
    // 2. Render ProductContainer based on category. If this.state.category.length is true - filter "prod" & where prod.categories is same type and name as this.state.category : else render all this.state.categories that matches "paint".
    return (
      <div>
        <Menu />
        <div className="archive-container">
          <div className="archive-wrapper">
            <CategoryContainer
              filterHandler={this.filterHandler}
              products={this.state.products}
            />
            <br/><br/>
            <ProductContainer
              products={this.state.category.length
                ? this.state.products.filter((prod) => prod.category === this.state.category)
                : this.state.products.filter((prod) => prod.category === 'paint')
              }
            />
          </div>
        </div>
        <Footer />
      </div>
    );
  };
};

export default Archive;

I am using webpack to bundle my project, and my entry is:

const entry = [
    'webpack-dev-server/client?http://localhost:8080', // bundle the client for webpack-dev-server and connect to the provided endpoint
    'webpack/hot/only-dev-server', // bundle the client for hot reloading only- means to only hot reload for successful updates
    './app.js'
]

..and my dev-server.js file looks like this:

var WebpackDevServer = require('webpack-dev-server');
var webpack = require('webpack');
// requiring my webpack configuration
var config = require('./webpack.config.js');
var path = require('path');

var compiler = webpack(config);
// then spinning up a new dev server with some settings
var server = new WebpackDevServer(compiler, {
    hot: true,
    filename: config.output.filename,
    publicPath: config.output.publicPath,
    proxy: {
        "/getMail": 'http://localhost:80/magdan/php/mailer.php',
        "/getProducts": 'http://localhost:80/magdan/php/products.php'
    },
    stats: {
        colors: true
    }
});

// its gonna listen to port 8080
server.listen(8080, 'localhost', function() {
    console.log("Starting server on http://localhost:8080");
});

I only get errors:

ERROR!!! Unexpected token C in JSON at position 0

I'm super thankful for any type of input!


Solution

  • Your PHP files aren't outputting JSON.

    Your fetch handler is calling res.json():

    const data = await res.json();
    

    That expects the output to be properly formatted JSON, but your PHP file is outputting "Connected":

    echo "Connected successfully";
    

    You need to change your PHP file to return valid JSON.