2

I have a React app that is connected to the backend via Express, where I query an SQL database to retrieve data. Final goal is to display that data via React.

Problem

I can't map through the list of elements returned by the SQL query. I'm too much of a beginner to tell why, but my guess is that it's because the returned data from the SQL query is an object, and I need an array to map it. So it returns an error: TypeError: this.state.allwatches.filter is not a function.

Server.js (seems to be working)

const express = require('express');
const app = express();
const port = 5000;  
var mysql      = require('mysql');  

var connection = mysql.createConnection({
    host     : '127.0.0.1',
    user     : 'root',
    password : 'password',
    database : 'Watches'
});

app.get('/getWatchesList', (req, res) => {
    connection.connect();
    connection.query('SELECT * from WatchesList', function(err, rows, fields) {
        if (!err) {
            res.send(JSON.stringify(rows));
        } else {
            console.log('Error while performing Query.');
        }
    });
    connection.end();
});

app.listen(port, () => console.log(`Server started on port ${port}`));

WatchesList.js (seems to cause problems)

import React, { Component } from 'react';

// Components
import Watche from './WatchesList_Components/Watche.js'

class WatchesList extends Component {
  constructor() {
    super();
    this.state = 
    {
      allwatches : ''
    };
  }

  componentDidMount() {
    fetch('/getWatchesList')
      .then(res => res.json())
      .then(allwatches_ => this.setState({allwatches: allwatches_}, () => console.log("successfully fetched allwatches", allwatches_)))
  }

  render() {
    let filteredWatches = this.state.allwatches.filter((watche) => {
        return watche.name.indexOf(this.props.filterText) > -1;
    });
    return (
        <div>
        { 
            filteredWatches.map(
                (product) => {
                return <Watche name={product.name} price={product.price} image={product.image} />
            })
        } 
        </div>
    ); 
  }
}

export default WatchesList;
2
  • You clearly state in your code that allwatches is just an empty string. Maybe that's a mistake or it needs to be populated properly? You may also be failing to wait for that async call to run, so componentDidMount may need to return a promise, or wait for the result. Commented Feb 3, 2018 at 19:30
  • @tadman I don't understand. I set allwatches to nothing initially, but then componentDidMount should update its state and insert the data in it. Commented Feb 3, 2018 at 19:43

1 Answer 1

1

Solved.

I had to replace in server.js res.json(rows); instead of res.send(JSON.stringify(rows));, and in my component I had to add an empty array in my state, so I went from allwatches : '' to allwatches : [] `

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

1 Comment

You should be careful when initializing things to nonsense values like that. A lot of JavaScript code is asynchronous meaning the order of operations is not always obvious. Whenever possible leave things uninitialized rather than populated with dummy values like an empty string. I think this "fix" makes that code operate on your empty array without error until it's properly populated, but that might not be your intent.

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.