I am trying to build a react application which saves data into database.
I have the following classes:
server.js
let express = require('express'); let bodyParser = require('body-parser'); let morgan = require('morgan'); let pg = require('pg'); let cors = require('cors'); const PORT = 3000; let pool = new pg.Pool({ user: 'admin', database: 'dev', password: 'password', host: 'localhost', port: 5432, max: 10 }); let app = express(); app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(morgan ('dev')); app.use(function(request, response, next) { response.header("Access-Control-Allow-Origin", "*"); response.header("Access-Control-Allow-Headers", "Origin, X-Requested- With, Content-Type, Accept, Authorization") next(); }); app.get('/api/creditcards', function(request, response) { pool.connect(function(err, db, done) { if (err) { return response.status(400).send(err); } else { db.query('SELECT * FROM creditcards', function(err, table) { done(); if (err) { response.status(400).send(err) }else { response.status(200).send(table.rows) } }) } }) }); app.post('/api/new-card', function(request, response) { var cardholder = request.body.cardholder; var cardnumber = request.body.cardnumber; var card_identifier = request.body.card_identifier; var expiration = request.body.expiration; var cvc = request.body.cvc; let values = [cardholder, cardnumber, card_identifier, expiration, cvc]; pool.connect((err, db, done) => { if(err) { return response.status(400).send(err); } else { db.query('INSERT INTO creditcards (cardholder, cardnumber, card_identifier, expiration, cvc) VALUES ($1, $2, $3, $4, $5)', [cardholder, cardnumber, card_identifier, expiration, cvc] ,(err, table) => { done(); if (err) { return response.status(400).send(err) } else { console.log('DATA INSERTED'); response.status(201).send({message : 'Data inserted...'}) } }) } }) }); app.listen(PORT, () => console.log('Listening on port ' + PORT));
and SaveNewCard.js
import React from 'react'; import Modal from './Modal'; import Payment from 'payment'; import { Row, Col, FormGroup, ControlLabel, Button, Alert, Grid } from 'react-bootstrap'; class SaveNewCard extends React.Component { constructor() { super(); this.state = { creditcards: [], isLoading: false, error: null, } } componentDidMount() { const { cardnumber, expiration, cvc } = this.refs; Payment.formatCardNumber(cardnumber); Payment.formatCardExpiry(expiration); Payment.formatCardCVC(cvc); console.log('Component has mounted') var that = this; fetch('http://localhost:3000/api/creditcards') .then(response => { console.log(response) if (response.ok) { return response.json(); } else { throw new Error('Something went wrong ...'); } }) .then(data => that.setState({ creditcards: data.creditcards, isLoading: false })) .catch(error => this.setState({ error, isLoading: false })); } addCreditCard(event) { var that = this; event.preventDefault(); let card_data = { cardholder : this.refs.cardholder.value, cardnumber : this.refs.cardnumber.value, card_identifier : (this.refs.cardnumber.value).substr(15), expiration : this.refs.expiration.value, cvc : this.refs.cvc.value }; console.log('Ez itt: ' + JSON.stringify(card_data)) var request = new Request('http://localhost:3000/api/new-card', { method: 'POST', headers: new Headers({ 'Content-Type': 'application/json', }), body: JSON.stringify(card_data) }); let creditcards = that.state.creditcards; creditcards.push(card_data); that.setState({ creditcards : creditcards }) console.log(creditcards) fetch(request) .then(response => { console.log(request) if (response.ok) { return response.json(); } else { throw new Error('Something went wrong ...'); } }) .then(data => this.setState({ creditcards: data.creditcards })) .catch(error => this.setState({ error })); } cardList() { return (<ul className="credit-card-list clearfix"> <Alert fluid style={{ paddingLeft: 40}} bsStyle="warning"> <strong>Please consider that only the following credit cards can be accepted:</strong> <li><i data-brand="visa" className="fa fa-cc-visa">VISA</i></li> <li><i data-brand="amex" className="fa fa-cc-amex">AMEX</i></li> <li><i data-brand="mastercard" className="fa fa-cc-mastercard">Master Card</i></li> </Alert> </ul>); } saveNewCardForm() { let creditcards = this.state.creditcards; return ( <div> <form className="SaveNewCard" onSubmit={ this.handleSubmit } style={{ paddingLeft: 40, paddingRight: 600}}> <Grid fluid style={{ paddingLeft: 60, paddingRight: 60}}> <Row> <Col xs={12}> <FormGroup> <ControlLabel>Cardholder Name</ControlLabel> <input onKeyUp= {this.setCardType} className="form-control text-center" type="text" ref="cardholder" placeholder="Your Name" /> </FormGroup> </Col> </Row> <Row> <Col xs={ 12 }> <FormGroup> <ControlLabel>Card Number</ControlLabel> <input onKeyUp={ this.setCardType } className="form-control text-center" type="text" ref="cardnumber" placeholder="Card Number" /> </FormGroup> </Col> </Row> </Grid> <Grid fluid style={{ paddingLeft: 60, paddingRight: 60}}> <Row > <Col xs={ 6 } sm={ 5 }> <FormGroup> <ControlLabel>Expiration</ControlLabel> <input className="form-control text-center" type="text" ref="expiration" placeholder="MM/YYYY" /> </FormGroup> </Col> <Col xs={ 6 } sm={ 4 } smOffset={ 3 }> <FormGroup> <ControlLabel>CVC</ControlLabel> <input className="form-control text-center" type="text" ref="cvc" placeholder="CVC" /> </FormGroup> </Col> </Row> </Grid> <Button bsStyle="primary" onClick={this.addCreditCard.bind(this)}>Submit</Button> <Button onClick={this.removeCreditCard.bind(this)}>Delete</Button> </form> <ul> {creditcards.map((creditcards => <li>{creditcards.cardholder}</li>))} </ul> </div>); } render() { return (<div className="CreditCard"> { this.cardList() } { this.saveNewCardForm() } </div>); } } SaveNewCard.propTypes = {}; export default SaveNewCard;
But I got the following Bad Request 400 error:
And:
As I can understand, my request does not contain the inserted data… I assume the problem is here somewhere….:
I let to write the “card_data” content to the console, it is there:
Any idea, why am I getting nulls as input data?
Sorry for this long post….
UPDATE:
The code fails at this line:
I replaced the “request.body.XY” variables with direct input and in that case the insert to database was working…. It may something with my request…
Advertisement
Answer
the problem is that you are not using fetch correctly . to do a post request you should do it like so :
const options = { method: 'post', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify(card_data) } fetch('http://localhost:3000/api/new-card', options) .then(response => { console.log(request) if (response.ok) { return response.json(); } else { throw new Error('Something went wrong ...'); } }) .then(data => this.setState({ creditcards: data.creditcards })) .catch(error => this.setState({ error }));