Insert into SQL database from React front end - sql

Im trying to insert some data into a SQL table but Im getting nothing from the front or back end I have tried console.log at various intervals but I cant seem to get data from either side.
For reference I have table called products with three columns id, name, image Im trying to insert both name and image with a button click. Additionally im trying to delete data thats been inserted and that also does nothing.
I have already achieved this with one table but that table only has one column.
Heres the front end
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import Helmet from 'react-helmet';
export default function Products() {
const [rows, setRows] = useState([]);
const [name, setName] = useState('');
const [src, setSrc] = useState('');
useEffect(() => {
axios.get('/products/get')
.then(res => {
setRows(res.data);
}).catch(err => {
console.log(err);
});
});
//Insert into database api request
const insertRow = () => {
axios.post('/products/insert', {
row: {name: name, image: src}
});
console.log(name, src);
};
//Delete from database api request
const deleteRow = () => {
axios.delete(`/products/delete/${name, src}`);
};
return (
<>
<Helmet>
<title>Title | products</title>
</Helmet>
<div className="pt-36 sm:pt-44 pb-20 md:pb-48 max-w-[1200px] mx-5 lg:mx-auto">
<input className="border-2 border-black p-1" type="text" onChange={setName} />
<input className="border-2 border-black p-1" type="text" onChange={setSrc} />;
<button className="border-2 border-l-0 border-black p-1" onClick={insertRow}>Submit</button>
{rows.map((row, index) => {
return (
<div key={index}>
<p>{row.name}</p>
<img src={row.image} alt={row.name} />
<button onClick={() => {deleteRow(row)}}>Delete</button>
</div>
)
})}
</div>
</>
);
};
And the back end
const express = require('express');
const cors = require('cors');
const db = require('./config/db');
const app = express();
const PORT = process.env.PORT || 8080;
//Dependencies
app.use(express.json());
app.use(cors());
//#region Products table
app.get('/products/get', (req, res) => {
const selectAll = 'SELECT * FROM products';
db.query(selectAll, (err, rows) => {
if (err) throw err;
res.send(rows);
});
});
//Insert into database
app.post('/products/insert', (req, res) => {
const row = req.body.row; //Row to insert
const insertRow = "INSERT INTO products (name, image) VALUES (?, ?)"; //Insert query
db.query(insertRow, [row], (err, rows) => { //Insert row into database
if (err) throw err;
console.log('inserted: ' + row); //Print row inserted
});
console.log(row);
});
//Delete from database
app.delete('/products/delete/:row', (req, res) => {
const row = req.params.row;
const deleteRow = "DELETE FROM products WHERE name = ?";
db.query(deleteRow, [row], (err, rows) => {
if (err) throw err;
console.log('deleted: ' + row);
});
});
//#endregion
//Server port
app.listen(process.env.PORT || PORT, () => {
console.log('Server started on port ' + PORT);
});

You have a problem in your frontend code, the setName and setSrc are done improperly:
return (
<input className="border-2 border-black p-1" type="text" onChange={setName} />
<input className="border-2 border-black p-1" type="text" onChange={setSrc} />;
)
Here's how it should be:
return (
<input className="border-2 border-black p-1" type="text" onChange={(event) => setName(event.target.value)} />
<input className="border-2 border-black p-1" type="text" onChange={(event) => setSrc(event.target.value)} />;
)

Related

how dropdown selected id pass vue to services.js file

how id pass vue to services.js
api.services.js
return axios.get(API_URL+'/product/all?id='+custom_id})
.then((res) => res.data);
tobar.vue
<script setup>
const dropdownItem = 1;
const dropdownItems = computed(() => items);
onMounted(() => {
ApiService.getStores().then(data => {
data.forEach(value => {
items.push({ name: value.shop, value: value.id });
});
});
});
const onChange = event => {
console.log(event.value);
};
</script>
<template>
<Dropdown
id="state"
v-model="dropdownItem"
:options="dropdownItems"
:filter="true"
optionLabel="name"
optionValue="value"
:placeholder="value"
#change="onChange"
/>
</template>
1- const onChange (event.value) how to pass (API_URL+'/product/all?id='+custom_id) custom_id in api.services.js to get data
2- const dropdownItem = 1; v-model="dropdownItem" default value selected its not working, how to solve this

Using Quasar q-select with a filter enabled when options is a json object

I cannot find any examples using composition api for this and could use some direction. I have a q-select which passes options as a prop using a axios request. The data is in this form:
[{description: "Apple Inc.", displaySymbol: "AAPL"}, {description: "Microsoft", displaySymbol: "MSFT"}]
I have about 20000 records in this JSON response. I am able to display it all in a v-select using:
<q-select
class="grey-7"
filled
v-model="addStockSymbol"
use-input
input-debounce="0"
label="Add New Stock Symbol"
:options="stockTickers"
option-label="description"
option-value="displaySymbol"
#blur="addPosition"
#filter="filterFn"
behavior="menu"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
No results
</q-item-section>
</q-item>
</template>
</q-select>
My issue is I do not know how to setup the filter and update function so I can search this. So far I have the code below but the examples on quasar do not use any arrays with objects but rather simple arrays. So I am wondering how do I approach this?
<script>
import {watch, ref, defineComponent,onMounted} from 'vue'
import {usePortfolioStore} from '../stores/portfolio-store'
import {storeToRefs} from 'pinia'
import {finnhubAPI} from 'boot/axios'
export default defineComponent({
name: 'UploadPositions',
components: {
},
setup () {
//v-models
const addStockSymbol = ref('')
const addShareCount = ref('')
const stockTickers = ref([])
const loadData = () => {
finnhubAPI.get('/api/v1/stock/symbol?exchange=US&token=tedkfjdkfdfd')
.then((response) => {
stockTickers.value = response.data
})
.catch(() => {
console.log('API request failed')
})
}
const filterFn = (val, update) => {
if (val === '') {
update(() => {
stockTickers.value =
})
return
}
}
update(() => {
const needle = val.toLowerCase()
this.options = stringOptions.filter(v => v.toLowerCase().indexOf(needle) > -1)
})
//add on mount API request
onMounted(() => {
loadData()
})
return {
addStockSymbol, addShareCount, portfolio, addPosition, deletePosition,
loadData, stockTickers, modifyTickerData, filterFn, update
}
}
})
</script>
Basically you need to store a complete copy of the response data and keep that around, untouched, so that each time the filter function is called you can filter off of that, looking within its objects for the label prop.
When setting up refs:
//v-models
const addStockSymbol = ref('')
const addShareCount = ref('')
const stockTickers = ref([])
const allResponseData= ref([]) // <-- add this one
Then your loadData function:
const loadData = () => {
finnhubAPI.get('/api/v1/stock/symbol?exchange=US&token=cc8ffgiad3iciiq4brf0')
.then((response) => {
const responseData = response.data.map((item) => ({label: item.description, value: item.displaySymbol}));
allResponseData.value = [...responseData];
stockTickers.value = [...responseData];
})
.catch(() => {
console.log('API request failed')
})
}
Then in your filter function:
const filterFn = (val, update, abort) => {
update(() => {
const needle = val.toLowerCase()
stockTickers.value = allResponseData.value.filter(option => {
return option.label.toLowerCase().indexOf(needle) > -1
})
})
}
See it in action:
const { ref } = Vue
const stringOptions = [
{label: 'Google', value: "goog"}, {label:'Facebook',value:'fb'}, {label:'Twitter', value: "twit"},{label: 'Apple', value: 'App'}]
const app = Vue.createApp({
setup () {
const options = ref(stringOptions)
return {
model: ref(null),
options,
filterFn (val, update, abort) {
update(() => {
const needle = val.toLowerCase()
options.value = stringOptions.filter(option => {
return option.label.toLowerCase().indexOf(needle) > -1
})
})
}
}
}
})
app.use(Quasar, { config: {} })
app.mount('#q-app')
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/quasar#2.7.7/dist/quasar.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/vue#3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar#2.7.7/dist/quasar.umd.prod.js"></script>
<!--
Forked from:
https://quasar.dev/vue-components/select#example--basic-filtering
-->
<div id="q-app" style="min-height: 100vh;">
<div class="q-pa-md">
<div class="q-gutter-md row">
<q-select
filled
v-model="model"
use-input
hide-selected
fill-input
input-debounce="0"
:options="options"
#filter="filterFn"
hint="Basic filtering"
style="width: 250px; padding-bottom: 32px"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
No results
</q-item-section>
</q-item>
</template>
</q-select>
</div>
</div>
</div>

issues getting data to show on screen from SQL

This is a React Js project that is using Axios, Cors, Express, and Node JS connecting to an SQL database.
I am trying to get the data from an SQL table and have it show on the screen either in a div or p tag each row on its own line. At this time I am able to get it to console.log inside my VS Code terminal from my server.js side as well as console log the data inside my browser console from my frontend of ProductList.js. I do not get any errors in any of my consoles just the data that I would like displayed on the screen.
The below is my server.js
const bodyParser = require('body-parser');
const express = require('express');
cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/collectors', function (req, res) {
var sql = require("mssql");
const config = {
user: 'XXXXXXX',
password: 'XXXXXXX',
server: 'XXXXXXX',
database: 'XXXXXXX',
options: {
trustServerCertificate: true,
trustedConnection: false,
enableArithAbort: true
},
}
sql.connect(config).then(pool => {
return pool.request()
.query('select * from CollectorAssignment.tCollectors ').then(result => {
console.dir(result)
res.send(result)
})
}).catch(err => {
console.log("error at line24: ", err)
})
sql.on('error', err => {
console.log("error at line28: ", err)
})
});
app.listen(5000, () => {
console.log('listening on port 5000')
});
The below is my ProductList.js
import React from "react";
import axios from 'axios';
class ProductList extends React.Component {
state = {
loading: true,
error: "",
data: []
};
componentDidMount() {
this.getCollectorList();
}
getCollectorList = () => {
this.setState({ loading: true });
return axios
.get(
'http://localhost:5000/collectors'
)
.then(result => {
console.log(result);
this.setState({
CollectorList: result.data.items,
loading: false,
error: false
});
})
.catch(error => {
console.error("error: ", error);
this.setState({
error: `${error}`,
loading: false
});
});
};
render() {
const { loading, error, data } = this.state;
if (loading) {
return <p className="productList">Loading ...</p>;
}
if (error) {
return (
<p className="productList">
There was an error loading the collectors.{" "}
<button onClick={this.loadData}>Try again</button>
</p>
);
}
return (
<div className="productList">
<h1>Collector List</h1>
{data.map(result => <p className="productList">{result.CollectorList}</p>)}
</div>
);
}
}
export default ProductList;
Screenshot of my VS Code console data I get the same info in my browser console which is a total of 16 rows of data that I need displayed on the screen
I have gotten this to start working for me here are the changes I have made to the two files I provided. I was calling a few areas improperly and found that I was looking at some ways for SQL and I am using SQL so some connections to the DB were different which caused some issues small syntax things mainly.
Server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const config = require('./src/dbfiles/dbConfig')
const app = express();
app.use(cors());
app.use(bodyParser.json({ extended: true }));
var sql = require("mssql");
app.get('/getCollectors', (req, res) => {
sql.connect(config).then(pool => {
return pool.request()
.query('SELECT * FROM CollectorAssignment.tCollectorsTest').then(result => {
res.send(result.recordset)
})
})
})
app.post('/addCollector', function (req, res) {
sql.connect(config).then(pool => {
return pool.request()
.query(`INSERT INTO CollectorAssignment.tCollectorsTest
(
Active,
FirstName,
MiddleInitial,
LastName,
CollectorCode,
CreationDate,
CollectionTeamID
) VALUES (
${req.body.Active},
'${req.body.FirstName}',
'${req.body.MiddleInitial}',
'${req.body.LastName}',
'${req.body.CollectorCode}',
'${req.body.CreationDate}',
1
)`)
.then(result => {
res.send(result)
})
})
});
app.post('/updateCollector', function (req, res) {
sql.connect(config).then(pool => {
return pool.request()
.query(`UPDATE CollectorAssignment.tCollectorsTest
SET ${req.body} = ${req.body}
WHERE ${req.body} = ${req.body}
`)
.then(result => {
res.send(result)
})
})
});
app.delete('/deleteCollector/:CollectorID', (req, res) => {
sql.connect(config).then(pool => {
return pool.request()
.query(`DELETE FROM CollectorAssignment.tCollectorsTest WHERE CollectorID = ${req.params.CollectorID}`).then(result => {
res.send(result.recordset)
})
})
})
app.listen(5000, () => {
console.log('running on port 5000');
})
ProductList.js
import "./userList.css";
import React from "react";
import axios from 'axios';
import { Link } from "react-router-dom";
import { DeleteOutline, Edit } from "#material-ui/icons";
class UserList extends React.Component {
state = {
Collectors: '',
collectorList: []
}
componentDidMount() {
this.getCollectors()
}
getCollectors = () => {
axios.get('http://localhost:5000/getCollectors')
.then((result) => result.data)
.then((result) => {
this.setState({collectorList: result});
});
};
render() {
return (
<div className="userList">
<h3>Collectors</h3>
<table className="blueTableHeaders">
<thead>
<tr>
<th>Active</th>
<td>Collectors</td>
<td>Aging Bucket</td>
<td>Program Code</td>
<td>Finance Company</td>
<td></td>
</tr>
</thead>
</table>
{this.state.collectorList.map((Collectors) => (
<div>
<table className="blueTableData">
<thead>
<tr>
<th><input type="checkbox" name="Active" defaultChecked={Collectors.Active === false ? false : true}/></th>
<td>{Collectors.FirstName} {Collectors.LastName} | {Collectors.CollectorCode}</td>
<td>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</td>
<td>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</td>
<td>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</td>
<td>
<Link to="/updateUser:CollectorID">
<Edit className="editCollector" />
</Link>
<Link to="/deleteUser:CollectorID">
<DeleteOutline className="deleteCollector"/>
</Link>
</td>
</tr>
</thead>
</table>
</div>
))}
<Link to="/newUser">
<button className="userListAddButton">Add Collector</button>
</Link>
<Link to="/deleteUser">
<button className="userListDeleteButton">Delete Collector</button>
</Link>
</div>
);
}
}
export default UserList;

Cant´t get cookie - Express

I created a server with express and have some get/post routes.
In the login page, I have a page that shows the form to login:
app.get("/login", (req, res) => {
res.send(`<h1>Iniciar sesión</h1>
<form method='post' action='/login'>
<input type='email' name='email' placeholder='Email' required />
<input type='password' name='password' placeholder='Contraseña' required />
<input type='submit' value='Ingresar' />
</form>
<a href='/register'>Registrarse</a`);
});
Then I have a Post method in which I set the cookies:
app.post("/login", (req, res) => {
const { email, password } = req.body;
const user = users.filter(
(e) => e.email === email && e.password === password
);
if (user.length >= 1) {
res.cookie("userId", user.id);
res.cookie("password", user.password);
res.redirect("/home");
} else {
console.log("contraseña incorrecta");
res.redirect("/login");
}
});
The problem is that when I go to this route, the user.name and user.email are undefined. In other words, I can´t acces to the cookie:
app.get("/home", (req, res) => {
const id = req.cookies.userId;
console.log(id); //this is undefined
const user = users.filter((u) => u.id === id);
//console.log(user);
res.send(`
<h1>Bienvenido ${user.name}</h1>
<h4>${user.email}</h4>
<a href='/'>Inicio</a>
`);
});
Advices?
Here is the complete code:
const express = require("express");
const morgan = require("morgan");
const cookieparser = require("cookie-parser");
const bodyparser = require("body-parser");
const app = express();
const users = [
{ id: 1, name: "Franco", email: "Franco#mail.com", password: "1234" },
{ id: 2, name: "Toni", email: "Toni#mail.com", password: "1234" },
];
app.use(morgan("dev"));
app.use(cookieparser());
app.use(bodyparser.urlencoded({ extended: true }));
app.use((req, res, next) => {
console.log(req.cookies);
next();
});
app.get("/", (req, res) => {
res.send(`
<h1>Bienvenidos a Henry!</h1>
${
req.cookies.userId
? `<a href='/home'>Perfil</a>
<form method='post' action='/logout'>
<button>Salir</button>
</form>
`
: `
<a href='/login'>Ingresar</a>
<a href='/register'>Registrarse</a>`
}
`);
});
app.get("/register", (req, res) => {
res.send(`<h1>Registrarse</h1>
<form method='post' action='/register'>
<input name='name' placeholder='Nombre' required />
<input type='email' name='email' placeholder='Email' required />
<input type='password' name='password' placeholder='Contraseña' required />
<input type='submit' value='Registrarse' />
</form>
<a href='/login'>Iniciar sesión</a>`);
});
app.get("/login", (req, res) => {
res.send(`<h1>Iniciar sesión</h1>
<form method='post' action='/login'>
<input type='email' name='email' placeholder='Email' required />
<input type='password' name='password' placeholder='Contraseña' required />
<input type='submit' value='Ingresar' />
</form>
<a href='/register'>Registrarse</a`);
});
app.post("/login", (req, res) => {
const { email, password } = req.body;
const user = users.filter(
(e) => e.email === email && e.password === password
);
if (user.length >= 1) {
res.cookie("userId", user.id);
res.cookie("password", user.password);
res.redirect("/home");
} else {
console.log("contraseña incorrecta");
res.redirect("/login");
}
});
app.get("/home", (req, res) => {
const id = req.cookies;
console.log(id);
const user = users.filter((u) => u.id === id);
//console.log(user);
res.send(`
<h1>Bienvenido ${user.name}</h1>
<h4>${user.email}</h4>
<a href='/'>Inicio</a>
`);
});
app.listen(3000, (err) => {
if (err) {
console.log(err);
} else {
console.log("Listening on localhost:3000");
}
});
Part of your problem is that this code:
const user = users.filter(
(e) => e.email === email && e.password === password
);
produces an Array. So, user is an array.
Therefore when you do this:
res.cookie("userId", user.id);
res.cookie("password", user.password);
Both user.id and user.password are ignoring the match you got in user[0] and are referring to non-existent properties on the user array object. They will end up undefined and thus why res.cookie() is not setting a meaningful value.
You should, instead be doing this:
res.cookie("userId", user[0].id);
res.cookie("password", user[0].password);
But, please don't put a password in a user's cookie. There should be no reason to ever do that. Even more so when it's in plain text. If you want to know if the previous user is logged in or not, then use a cryptographically secure token in the cookie (like something express-session uses). Don't put their password in a cookie.

React adding new users to SQL database (undefined entries)

I have been making a website in which I am beginning to create a registration process.I have created the registration form and a server.js file using npm express. However this keeps throwing this error and I'm not sure why.
This is the error
TypeError: Cannot destructure property 'email' of 'req.body' as it is undefined.
All I want to do is so that when submit button is clicked it the users are simply added to the database.
This is the server.js (The error occurs within this file from what I can gather)
const express = require("express");
const sql = require("mssql");
const app = express();
const port = process.env.PORT || 5000;
app.listen(port, () => `Server running on port ${port}`);
const config = {
user: "sas",
password: "Mypassword456",
server: "DEVSQL_2014", // You can use 'localhost\\instance' to connect to named instance
database: "TestDBWebsite"
};
app.post("/admin-Add-Users", function(req, res) {
res.set("Access-Control-Allow-Origin", "*");
const { email, password } = req.body;
let connection = new sql.ConnectionPool(config, function(err) {
let request = new sql.Request(connection);
request.query(
"insert into Login (email, password) values ('" +
password +
"', '" +
email +
"')"
);
});
res.send({ message: "Success" });
});
register.js
import React from "react";
import "../bootstrap.min.css";
import logo from "../codestone logo.png";
import { Link } from "react-router-dom";
import Popup from "reactjs-popup";
import { Formik } from "formik";
import * as Yup from "yup";
function Register() {
return (
<div className="App">
<Header />
<DisplayUsersCS />
</div>
);
}
class DisplayUsersCS extends React.Component {
constructor() {
super();
this.state = { users: [] };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
var self = this;
// On submit of the form, send a POST request with the data to the server.
fetch("/admin-Add-Users", {
method: "POST",
body: {
email: self.refs.email,
password: self.refs.password
}
})
.then(function(response) {
return response.json();
})
.then(function(body) {
console.log(body);
});
}
render() {
console.log(this.state.users);
return (
<div>
<LoginForm></LoginForm>
<form onSubmit={this.onSubmit}>
<input type="text" placeholder="email" ref="email" />
<input type="text" placeholder="password" ref="password" />
<input type="submit" />
</form>
</div>
);
}
}
const LoginForm = () => (
<Formik
class="form-signin"
action="auth"
method="POST"
initialValues={{ email: "", password: "", passwordConfirm: "" }}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
console.log("Logging in", values);
setSubmitting(false);
}, 500);
}}
validationSchema={Yup.object().shape({
email: Yup.string()
.email()
.required("Required")
.matches(/(?=.*codestone)/, "This is not a Codestone email address."),
password: Yup.string()
.required("No password provided.")
.min(8, "Password is too short - should be 8 chars minimum.")
.matches(/(?=.*[0-9])/, "Password must contain a number."),
passwordConfirm: Yup.string()
.required("No password provided.")
.min(8, "Password is too short - should be 8 chars minimum.")
.matches(/(?=.*[0-9])/, "Password must contain a number.")
})}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<form
onSubmit={handleSubmit}
class="form-signin"
action="auth"
method="POST"
>
<div className="jumbotron">
<label htmlFor="email">Email</label>
<input
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={errors.email && touched.email && "error"}
/>
{errors.email && touched.email && (
<div className="input-feedback">{errors.email}</div>
)}
<label htmlFor="email">Password</label>
<input
name="password"
type="password"
placeholder="Enter your password"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
className={errors.password && touched.password && "error"}
/>
{errors.password && touched.password && (
<div className="input-feedback">{errors.password}</div>
)}
<label htmlFor="email">Password Confirmation</label>
<input
name="passwordConfirm"
type="passwordConfirm"
placeholder="Confirm Password"
value={values.passwordConfirm}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.passwordConfirm && touched.passwordConfirm && "error"
}
/>
{errors.passwordConfirm && touched.passwordConfirm && (
<div className="input-feedback">{errors.passwordConfirm}</div>
)}
<button type="submit" action="auth">
Sign Up
</button>
<p>
<Link to="/Login"> Login </Link>
</p>
<p>
<Link to="/reset"> Reset Password </Link>
</p>
</div>
</form>
);
}}
</Formik>
);
function Header() {
return (
<div class="jumbotron">
<img
className="profile-image"
alt="icon"
src={logo}
width="450"
height="80"
/>
</div>
);
}
export default Register;
On client side (react)
To use fetch to post json data, you need to stringify the data in the body
fetch('https://example.com/profile', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
On server side (express.js)
You need to include include middleware in order to read the request body. You can refer to the sample codes here https://github.com/expressjs/body-parser