Search code examples
mysqlnode.jsreactjsexpressknex.js

Why does Knex insert null values into my table database?


I have a SQLite database connected via express and have controllers to connect front end with backend using express routes.

Table database

  return knex.schema.createTable('stocks', (table)  => {
          table.string('ticker')
          table.date('date')
          table.integer('open')
          table.integer('close')
          table.integer('high')
          table.integer('last')
          table.integer('volume')
        })
        .then(() => {
         
          console.log('Table \'stocks\' created')
        })
        .catch((error) => {
          console.error(`There was an error creating table: ${error}`)
        })
      }
    })
    .then(() => {
      // Log success message
      console.log('Ayree')
    })
    .catch((error) => {
      console.error(`There was an error setting up the database: ${error}`)
    })

Knex Insert Rows

exports.booksCreate = async (req, res) => {
  // Add new book to database
  knex('stocks')
    .insert({ // insert new record, a book
      "ticker": req.body.ticker,
      'date': req.body.date,
      'open': req.body.open,
      'close': req.body.close,
      'high': req.body.high,
      'last': req.body.last,
      'volume': req.body.volume,
    })
    .then(() => {
      // Send a success message in response
      res.json({ message: ` \'${req.body.ticker}\' added at ${req.body.date} created.` })
    })
    .catch(err => {
      // Send a error message in response
      res.json({ message: `There was an error creating ${req.body.ticker}  ${err}` })
    })
}

React Front End

// Create Bookshelf component
export const Bookshelf = () => {
  // Prepare states
   const [stock, setStock] = useState([])
   const [stockApi, setStockApi] = useState([])
  const [loading, setLoading] = useState(true)

  // Fetch all books on initial render
  useEffect(() => {
   
    getStockData();
    handleBookCreate();
  }, [])


  //StockData
const getStockData = ()  => { 
    axios
    .get("http://api.marketstack.com/v1/intraday/latest?access_key=72ad8c2f489983f30aaedd0181414b43&symbols=AAPL"       )
    .then( da => {
       setStock(da.data.data[0]) 
        console.log(da.data.data[0])
    } )
} 

// Create new book
  const handleBookCreate = () => {
    // Send POST request to 'books/create' endpoint
    axios
      .post('http://localhost:4001/books/create', { 
        ticker: stock.symbol,
        date: stock.date,
        open: stock.open,
        close: stock.close,
        high: stock.high,
        last: stock.last,
        volume: stock.volume,
      })
      .then(res => {
        console.log(res.data)

        // Fetch all books to refresh
        // the books on the bookshelf list
        fetchBooks()
      })
      .catch(error => console.error(`There was an error creating the ${stock} book: ${error}`))
  }

The issue here is in the front end when i use stock.symbol i get a value of null but when i substitute stock.symbol with "text" i get the value text. What am i doing wrong here? Thanks!

P.S - Here is const stock

close: 115.08
date: "2020-10-09T00:00:00+0000"
exchange: "IEXG"
high: 116.4
last: 114.97
low: 114.5901
open: 116.25
symbol: "AAPL"
volume: 82322071
__proto__: Object

Solution

  • After some time reading about HTTP calls and how they are executed. This solution worked for me.

     useEffect( () => {
    
    const fetchData = async ( ) => { 
    
      const getit =  await getStockData(); setStock(getit); 
        handleBookCreate(getit); 
        } 
             fetchData();
    
      }, [])
    

    Basically on intial render useEffect, make the API call getStockData()and the await will make setting the stock setStock hook work after the promise have been executed. Only then the stock would contain the data needed for handleBookCreate() to send a POST request to the server router to execute the function to insert a record in my table database.