HTTP (Post) Bad Request 400 - How to solve?

1

I am making a post, but my server is not sending an error (400). Below is the server code.

    const express = require('express');
    const app = express();
    const bodyParser = require('body-parser');
    const mysql = require('mysql');
    const cors = require('cors')
    const corsOptions = {
        origin: 'http://localhost:4200',
        optionsSuccessStatus: 200
    }

    app.use(cors(corsOptions))

    app.use(bodyParser());
    app.use(bodyParser.urlencoded({
        extended: true
    }));

    // connection configurations
    const mydb = mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'xxxxxxx',
        database: 'xxxxxxx'
    });

    // connect to database
    mydb.connect();

    // default route
    app.get('/', function (req, res) {

    });

    // Retrieve all Quotes 
    app.get('/quotes', function (req, res) {
        mydb.query('SELECT * FROM quotes', function (error, results, fields) {
            if (error) throw error;
            return res.send(results);
        });
    });


    // Retrieve quote with id 
    app.get('/quotes/:id', function (req, res) {

        let quote_id = req.params.id;

        mydb.query('SELECT * FROM quotes where id=?', quote_id, function (error, results, fields) {
            if (error) throw error;
            return res.send(results[0]);
        });

    });

    // Add a new quote  
    app.post('/quotes', function (req, res) {

        let quote = req.body.quotes;
        console.log(quote)

        if (!quote) {
            return res.status(400).send({ error: true, message: 'Please provide quote' });
        }

        mydb.query("INSERT INTO quotes SET ? ", { quote: quote }, function (error, results, fields) {
            if (error) throw error;
            return res.send(results);
        });
    });

    //  Update quote with id
    app.put('/quotes', function (req, res) {

        let quote_id = req.body.quote_id;
        let quote = req.body.quote;

        if (!quote_id || !quote) {
            return res.status(400).send({ error: quote, message: 'Please provide quote and quote_id' });
        }

        mydb.query("UPDATE quotes SET quote = ? WHERE id = ?", [quote, quote_id], function (error, results, fields) {
            if (error) throw error;
            return res.send({ error: false, data: results, message: 'Quote has been updated successfully.' });
        });
    });

    //  Delete quote
    app.delete('/quote/:id', function (req, res) {

        let quote_id = req.params.id;

        mydb.query('DELETE FROM quotes WHERE id = ?', [quote_id], function (error, results, fields) {
            if (error) throw error;
            return res.send({ error: false, data: results, message: 'Quote has been updated successfully.' });
        });

    });

    // all other requests redirect to 404
    app.all("*", function (req, res, next) {
        return res.send('page not found');
        next();
    });

    // port must be set to 8080 because incoming http requests are routed from port 80 to port 8080
    app.listen(8080, function () {
        console.log('Node app is running on port 8080');
    });

    // allows "grunt dev" to create a development server with livereload
    module.exports = app;

Below is the service:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Quote } from './1-model/quote.model';
import { QuoteValue } from './1-model/QuoteValue.model'


const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
}

@Injectable({
  providedIn: 'root'
})

export class QuoteService {
  private quoteURL = 'http://localhost:8080/quotes'; //URL to web api
  constructor(private http: HttpClient) { }

  getQuotes(): Observable<Quote[]> {
    return this.http.get<Quote[]>(this.quoteURL)
  }

  getQuote(id: number): Observable<Quote> {
    const url = '${this.quoteURL}/${id}';
    return this.http.get<Quote>(url)
  }

  addQuote(quote: Quote): Observable<Quote> {
    return this.http.post<Quote>(this.quoteURL, quote, httpOptions)
  }

  deleteQuote(quote: Quote | number): Observable<Quote> {
    const id = typeof quote === 'number' ? quote : quote.id;
    const url = '${this.quoteURL}/${id}';
    return this.http.delete<Quote>(url, httpOptions)
  }

  updateQuote(quote: QuoteValue): Observable<any> {
    return this.http.put(this.quoteURL, quote, httpOptions)
  }
}

QUOTE Interface:

    export interface Quote {
        id: number
        QuoteType: string
        AccountOwner: string
        AccountContactName: string
        AccountContactEmail: string
        AccountContactTel: string
        AccountNumber: number
        PriceIncrease: string
        InitialTerm: number
        RenewalTerm: number
        FreeMonths: string
        EffectiveDate: string
        CageUniqueSpaceID: string
        IdOportunity: string
        IBX: string
        CloseDate: string
        ProjectStatus: string
        HasTerm: boolean
        NonStandardTerm:string
        FreeMonthsORRamp: string
        RampMonths: string
        RampStartDate: string
        RampEndDate: string
        RampPerCent: string
    }

Form sending the Post

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Quote } from '../../1-model/quote.model';
import { QuoteService } from '../../quote.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-form-migration',
  templateUrl: './form-migration.component.html',
  styleUrls: ['./form-migration.component.css']
})
export class FormMigrationComponent implements OnInit {

  public formMigration: FormGroup;
  public submitted: boolean = false;
  public hasTerm: boolean;
  @Input() public quotetype;

  constructor(
    private formBuilder: FormBuilder,
    private quoteService: QuoteService,
    private route: Router
    ) { }

  ngOnInit() {
    this.formMigration = this.formBuilder.group({
      QuoteType: [this.quotetype],
      AccountOwner: [null, Validators.required],
      AccountContactName: [null, Validators.required],
      AccountContactEmail: [null, [Validators.required, Validators.email]],
      AccountContactTel: [null, Validators.required],
      AccountNumber: [null, Validators.required],
      IdOportunity: [null, Validators.required],
      IBX: [null, Validators.required],
      ProjectStatus: ['In Progress', Validators.required],
      InitialTerm: [null, [Validators.max(60), Validators.min(1)]],
      RenewalTerm: [null, [Validators.max(60), Validators.min(1)]],
      PriceIncrease: [null],
      EffectiveDate: [null],
      HasTerm: [null, Validators.required],
      NonStandardTerm: [null],
    })

    this.formControlNonStandardTerm()
  }

  formControlNonStandardTerm() {
    const NonStandardTermControl = this.formMigration.get('NonStandardTerm');

    this.formMigration.get('HasTerm').valueChanges.subscribe(
      (data: string) => {
        this.hasTerm = this.formMigration.get('HasTerm').value
        if (data === 'Yes') {
          NonStandardTermControl.setValidators([Validators.required]);
        } else if (data === 'No') {
          NonStandardTermControl.clearValidators();
          this.formMigration.controls['NonStandardTerm'].setValue('');
        }
        NonStandardTermControl.updateValueAndValidity();
      }
    );
  }

  registerQuote() {
    const migrationQuote = this.formMigration.getRawValue() as Quote
    this.quoteService.addQuote(migrationQuote).subscribe()
    this.route.navigate(['homepage', 'quotes-abertas'])
  }

}

Error that I'm getting:

core.js:1673 ERROR 
HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: "Bad Request", url: "http://localhost:8080/quotes", ok: false, …}
error: {error: true, message: "Please provide quote"}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure response for http://localhost:8080/quotes: 400 Bad Request"
name: "HttpErrorResponse"
ok: false
status: 400
statusText: "Bad Request"
url: "http://localhost:8080/quotes"
__proto__: HttpResponseBase

Apparently I'm wrong with this part

    mydb.query("INSERT INTO quotes SET ? ", { quote: quote }, function (error, results, fields) {
        if (error) throw error;
        return res.send(results);
    });

Below is the response from the server I'm receiving!

PS C:\angular\node_API\api-checklist> node server.js
Node app is running on port 8080
{ QuoteType: 'Migration',
  AccountOwner: 'k2i2j\'i2',
  AccountContactName: 'eiwuiwu',
  AccountContactEmail: 'iwuiwueiw@r',
  AccountContactTel: '1212',
  AccountNumber: 1211,
  IdOportunity: '121',
  IBX: 'SP3',
  ProjectStatus: 'In Progress',
  InitialTerm: null,
  RenewalTerm: null,
  PriceIncrease: null,
  EffectiveDate: null,
  HasTerm: 'No',
  NonStandardTerm: '' }
C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\Parser.js:80
        throw err; // Rethrow non-MySQL errors
        ^

Error: ER_BAD_FIELD_ERROR: Unknown column 'quote' in 'field list'
    at Query.Sequence._packetToError (C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\sequences\Sequence.js:47:14)
    at Query.ErrorPacket (C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\sequences\Query.js:77:18)
    at Protocol._parsePacket (C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\Protocol.js:278:23)
    at Parser.write (C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\Parser.js:76:12)
    at Protocol.write (C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\Protocol.js:38:16)
    at Socket.<anonymous> (C:\angular\node_API\api-checklist\node_modules\mysql\lib\Connection.js:91:28)
    at Socket.<anonymous> (C:\angular\node_API\api-checklist\node_modules\mysql\lib\Connection.js:502:10)
    at Socket.emit (events.js:182:13)
    at addChunk (_stream_readable.js:283:12)
    at readableAddChunk (_stream_readable.js:264:11)
    --------------------
    at Protocol._enqueue (C:\angular\node_API\api-checklist\node_modules\mysql\lib\protocol\Protocol.js:144:48)
    at Connection.query (C:\angular\node_API\api-checklist\node_modules\mysql\lib\Connection.js:200:25)
    at C:\angular\node_API\api-checklist\server.js:66:10
    at Layer.handle [as handle_request] (C:\angular\node_API\api-checklist\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\angular\node_API\api-checklist\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\angular\node_API\api-checklist\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\angular\node_API\api-checklist\node_modules\express\lib\router\layer.js:95:5)
    at C:\angular\node_API\api-checklist\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (C:\angular\node_API\api-checklist\node_modules\express\lib\router\index.js:335:12)
    at next (C:\angular\node_API\api-checklist\node_modules\express\lib\router\index.js:275:10)
PS C:\angular\node_API\api-checklist>

Can anyone help me? Please.

    
asked by anonymous 28.09.2018 / 21:48

1 answer

0

The problem is that INSERT understands, in the way your code is, that you have a column named quote , which is not the reality. You must pass as second parameter an object with columns and values. Change your code to the following:

mydb.query('INSERT INTO quotes SET ? ', quote, function (error, results, fields) {
  if (error) throw error;
  return res.send(results);
});
    
29.09.2018 / 03:15