Search bar using Express and Node in MVC model - javascript

I have made a search bar on the customers page of my website and whatever string the admin enters in the search bar will be sent as a get request, and based on the input I am trying to find all the data in MySQL db which contains the input string inside of the fullname field.
My website build as MVC model, using Express to display data and Node.js
This is my form
<form class="d-flex" method="GET">
<input class="form-control me-2 py-1" type="text" id="search" name="search" placeholder="Search customer name" aria-label="Search" value="<%= %>" />
<button class="btn btn-sm btn-secondary" type="submit">Search</button>
</form>
This is route in web.js file
router.get('/customer?search',authentication.handleAuthentication, authadmin.authAdmin,adminController.searchCustomer);
getCustomerByName() inside adminServices.js
let getCustomerByName = (name) => {
return new Promise(async (resolve, reject) => {
try {
let user = await db.User.find({ fullname: name });
if (user) {
console.log(user);
resolve(user);
} else {
resolve(user);
}
} catch (e) {
reject(e);
}
});
};
searchCustomer() inside adminController.js
let searchCustomer = async (req,res,next) =>{
let name = req.params.search;
let customer = await adminServices.getCustomerByName(name);
return res.render('admin/customer.ejs', {
customer: customer,
});
}
I had tried req.body.search / req.params.search / req.query but seem like it can't get the input.
The URL like this: http://localhost:8080/customer?search=mai. I couldn't find where is the problem because there is nothing show in the console. Are there any method I could try?

You need to add action tag to form element. Change route name to just customer and use req.query.search in controller.
router.get('/customer', authentication.handleAuthentication, authadmin.authAdmin, adminController.searchCustomer);
let searchCustomer = async(req, res, next) => {
let name = req.query.search; // change params to query
let customer = await adminServices.getCustomerByName(name);
return res.render('admin/customer.ejs', {
customer: customer,
});
}
<form class="d-flex" action="/customer" method="GET">
<input class="form-control me-2 py-1" type="text" id="search" name="search" placeholder="Search customer name" aria-label="Search" value="<%= %>" />
<button class="btn btn-sm btn-secondary" type="submit">Search</button>
</form>

Related

Unable to redirect to homepage after posting a form - Express,EJS and JS

I have a view which contains a form and looks like this,
<form class="flex-form" id="form" method="">
<div class="form-component">
<label>Type</label>
<input type="text" id="type" name="type">
</div>
<div class="form-component">
<div class="form-component"><label><b>Contents</b></label></div>
<label>Savoury</label><input type="text" name="savoury" id="savoury">
<label>Fillings</label><input type="text" name="fillings" id="fillings">
<label>Amount</label><input type="text" name="amount" id="amount">
<div class="flex-component">
<button class="set-button" type="button" id="set">Set Item</button>
</div>
</div>
<div class="form-component">
<label class="description-label">Description</label>
<textarea class="fixed-textarea" id="description" name="description" cols="15" rows="10"></textarea>
</div>
<div class="form-component">
<label >Unit Price</label>
<input type="text" id="price" name="unit_price">
</div>
<div class="flex-component">
<button class="form-button" type="submit">Add</button>
</div>
</form>
I have a JavaScript that allows me to capture some intermediary information (via the Set Item button) from the form before the form gets submitted (via the Add Button). I want to handle the form's submission from the script since I need to capture the intermediary data.
let collectedItems = [];
let setter = document.getElementById('set');
let form = document.getElementById('form');
setter.addEventListener('click',getSetContent);
function getSetContent() {
let type = document.getElementById('savoury');
let fillings = document.getElementById('fillings');
let amount = document.getElementById('amount');
const content = {
type: type.value,
fillings: fillings.value.split(','),
amount: Number(amount.value)
};
collectedItems.push(content);
clearInputFields([type,fillings,amount]);
}
function clearInputFields(inputFields) {
inputFields.forEach(field => {
field.value = ''
});
console.log(collectedItems);
}
form.addEventListener('submit',submitForm);
function submitForm() {
const type = document.getElementById('type').value;
const desc = document.getElementById('description').value;
const price = Number(document.getElementById('price').value);
const content = collectedItems;
const data = {
type: type,
contents: content,
description: desc,
unit_price: price
};
post('http://localhost:8001/add/box',
{ 'Content-Type': 'application/json' },
JSON.stringify(data)
);
}
function post(endpoint,header,body) {
const response = fetch(endpoint,{ method: 'POST',headers: header,body: body });
response.then(
resp => {
if (resp.ok) {
console.log('form submitted');
} else {
console.log('form not submitted');
}
}
)
}
I then make a POST request using fetch() to an endpoint I have setup in Express which looks like this,
app.post('/add/box',(req,res) => {
const box: any = req.body;
console.log(box);
// DO SOME DB STUFF
res.redirect('/');
});
The form submission works as intended (logs to terminal using nodemon), however I am unable to redirect to the homepage. Instead I stay on the form page after the submission has occurred and I can't figure out why. Any help with this issue is much appreciated.

ReferenceError: Cannot access module before initialization

I already created my model 'order'
I try to add new order into my mongodb, but keep showing this error,please help me! Thanks
I rely on the add_order.ejs to submit the form.
"ReferenceError: Cannot access 'order' before initialization"
I have the other two model 'recipe' and 'customer',but they worked! I don't understand why only
order has error?
order.js
const userSchema = new mongoose.Schema({
order_id :{
type: String,required : true
},
sum :{
type:Number,
required : true,
},
account :{
type :String,
required : true,
}
});
module.exports = mongoose.model('order',userSchema);
routes.js
const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
const customer = require('../models/customer');
const recipe = require('../models/recipe');
const multer = require('multer');
const { GridFSBucketReadStream } = require('mongodb');
const fs = require('fs');
const order = require('../models/order');
//insert an order into database route
router.post('/add_order', upload, (req,res) => {
const order = new order({
order_id : req.body.order_id,
sum : req.body.sum,
account : req.body.account,
});
order.save((err) => {
if(err){
res.json({message : err.message, type :'danger'});
}
else{
req.session.message={
type:'success',
message :'Customer added successfully!'
};
res.redirect("/");
}
})
})
add_order.ejs
<form action="/add_order" method="POST" id="add-form" enctype="multipart/form-data">
<div class="one_third first">
<label for="name">order_id <span>*</span></label>
<input type="text" name="order_id" placeholder="Enter order_id" size="22" required /></td>
</div>
<div class="one_third">
<label for="email">sum <span>*</span></label>
<input type="number" name="sum" placeholder="Enter sum" size="22" required>
</div>
<div class="one_third">
<label for="url">account <span>*</span></label>
<input type="text" name="account" placeholder="Enter account" size="22" required />
</div>
<input type="submit" name="submit" value="Add order" />
<input type="reset" name="reset" value="Reset Form">
</form>
You have a problem on this:
const order = require('../models/order');
//insert an order into database route
router.post('/add_order', upload, (req,res) => {
const order = new order**({ // <- you trying to change an immutable class definition
Class variable and instance variable needs to have different names.
Recommend you to change your class name to Order (with capital O):
const Order = require('../models/order');
then call your instance like this:
const order = new Order({ ... });
See more

Cannot POST / login.html

I'm having trouble sending data to the server using a form. I already made a register form that works just fine, and for the most part my client side javascript for the login form is very similar to the javascript for the register form, and I just can't figure out why it won't work. It just gives me "Cannot POST /login.html"
Here's the login form html:
<div class="loginTitle">
<h1>Login</h1>
</div>
<div class="loginFormLayout">
<form method=post id="loginForm">
<div class="loginFormText">
<label for="username">Username</label>
</div>
<div class="loginFormEntry">
<input type="text" placeholder="Enter Username" name="loginUsername" required>
</div>
<div class="loginFormText">
<label for="password">Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Enter Password" name=loginPassword required>
</div>
<button type="submit" class="loginButton">Log In</button>
</form>
</div>
And here's the client side javascript:
//Login as an existing user
const login = document.getElementsByClassName('loginButton');
const loginForm = document.getElementById('loginForm');
const loginURL = 'http://localhost:3000/loginUser';
loginForm.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(loginForm);
let username = formData.get('loginUsername');
let password = formData.get('loginPassword');
loginForm.reset();
let user = { //Create a user object that will be sent to the backend and compared to the user database
username,
password
};
fetch(loginURL, { //Send the user object to the backend in JSON format to be checked against the database
method: 'POST',
body: JSON.stringify(user),
headers: {
'content-type': 'application/json'
}
})});
And the server side javascript for now, console logs are just to see if the info is getting up to the server
app.post('/loginUser', (req, res) => {
console.log(req.body.username);
console.log(req.body.password);
});
EDIT: I've also decided to post the info for my register form, which DOES work and uses similar logic to the login form. Maybe I'm missing something that isn't in the login logic
Register form html:
<div class="loginMenu">
<div class="loginTitle">
<h1>Register</h1>
</div>
<div id="registerWarning"></div>
<div class="loginFormLayout">
<form method="post" id="registerForm">
<div class="loginFormText">
<label for="username" id="newUsername">Username</label>
</div>
<div class="loginFormEntry">
<input type="text" placeholder="Create Username" name="username" required>
</div>
<div class="loginFormText">
<label for="password" id="newPassword">Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Create Password" name=password required>
</div>
<div class="loginFormText">
<label for="confirmPassword">Confirm Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Confirm Password" name="confirmPassword" required>
</div>
<button type="submit" class="registerButton">Register</button>
</form>
</div>
</div>
Register form client side javascript:
//Register a new user
const register = document.getElementsByClassName('registerButton');
const registerForm = document.getElementById('registerForm');
const registerURL = 'http://localhost:3000/createNewUser';
//When the user presses the register button, get the info from the form
registerForm.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(registerForm);
let newUsername = formData.get('username');
let newPassword = formData.get('password');
let confirmPassword = formData.get('confirmPassword')
registerForm.reset();
//Make sure new password and confirm password are equal
if (newPassword == confirmPassword) {
if (newUsername != "" && newPassword != ""){ //Make sure user enters something for both fields
let newUser = { //Create an object to send to the back end
newUsername,
newPassword
};
fetch(registerURL, { //Send the newUser object to the backend in JSON format to be added to the database
method: 'POST',
body: JSON.stringify(newUser),
headers: {
'content-type': 'application/json'
}
});
}
}
else { //If newPassword and confirmPassword are not equal, ask the user to enter them correctly
const registerWarning = document.getElementById('registerWarning');
registerWarning.innerText = 'Password and Confirm Password do not match';
registerWarning.style.padding = "10px";
registerWarning.style.background = 'red';
};
});
Register form server-side javascript:
app.post('/createNewUser', (req, res) => {
let newUsername = req.body.newUsername;
let newPassword = req.body.newPassword;
let newUserData = 'INSERT INTO users (username, password) VALUES (?, ?)';//Use the question marks as placeholders
//Use bcrypt to hash the password before putting it in the database
bcrypt.hash(newPassword, saltRounds, function(err, hash) {
db.query(newUserData, [newUsername, hash], function(err, result) {
if (err) throw err;
console.log('New user registered');
});
});
});
I figured it out, thanks to #Rocky Sims for the help.
Basically, the register form doesn't exist on the login html page, which was throwing an error up about how that doesn't exist before it could even get to the login code. So I just had to make seperate register.js and login.js files, as the issue was due to them being in the same file.
Try wrapping your form method (post) in quotes ('') like so <form method='post' id="loginForm">
Also the value for the name attribute for your password input should by in quotes. Like so <input type="password" placeholder="Enter Password" name='password' required>
I think the problem is that you haven't told the server what to send back to the client when the POST /loginUser endpoint gets called. Try adding res.sendStatus(200); at the end of your POST /loginUser handler function (so right after console.log(req.body.password);).

How to insert particular values into Mongodb using Angularjs MEAN STACK

I store input values into mongodb using scope name. I have a 3 fields when I click add all values are in object so I directly send the scope name into server and store it.
I would like to store only 2nd textbox values and remaining values should be NULL into the database. But I don't know how to do this. Anyone can help me?
Server.js
app.post('/AddNewcontact', function (req, res) {
db.Manage_Facility.insert(req.body, function (err, docs) {
console.log(docs);
res.json(docs);
});
});
controller.js
$scope.AddNew = function () {
$http.post('/AddNewcontact', $scope.Contact).success(function (response) {
});
};
html
<input type="text" name="Name" class="form-control" ng-model="Contact.Name">
<input type="text" name="email" class="form-control" ng-model="Contact.email">
<input type="text" name="cellno" class="form-control" ng-model="Contact.cellno">
<button class="btn btn-primary" ng-click="AddNew()" >Submit</button>
controller.js
$scope.AddNew = function () {
$http.post('/AddNewcontact',{ 'Name': $scope.Contact.email}).success(function (response) {
});
};
Let's say you want to send just the email, do following :
delete $scope.Contact.Name;
delete $scope.Contact.cellno;
here is example
$http.post('/AddNewcontact', $scope.Contact).success(function (response) {
});

how to post data to server using angularJS, web api

i am new to angularJS and trying to figure out, how to post data to my server, problem is that my post to server is successful and it create new record but all is empty(null).
Thanks for any advice
JS:
$scope.addChannel = function () {
var channels = [];
//var newChannel = {
// Name: $scope.Name
//};
//clearing error message
$scope.errorMessage = "";
$http.post("api/Channel/channels", newChannel)
.success(function (newChannel) {
//on success
$scope.channels.push({ "Name": $scope.Name });
console.log("data added");
// newChannel.push(response.data);
newChannel = {};
}, function () {
//on failure
$scope.errorMessage = "Failed to save data";
})
}
HTML:
<div ng-controller="ChannelController">
<div class="col-md-4 col-lg-4 col-sm-4">
<form novalidate name="newUser"ng-submit="addChannel()">
<div class="form-group">
<label for="name">Channel</label>
<input class="form-control" type="text" id="Name" name="Name" ng-model="newChannel.Name" />
</div>
<div class="form-group">
<input type="submit" value="Add" class="btn btn-success" />
</div>
</form>
<a ng-href="/Dashboard#/channels">Return to dashboard</a>
</div>
<div class="has-error" ng-show="errorMessage">
{{errorMessage}}
</div>
Channel Controller
[HttpPost("channels")]
public async System.Threading.Tasks.Task Create(Channel channel)
{
await _channelRepository.CreateChannel(channel);
}
Repository
public async System.Threading.Tasks.Task CreateChannel(Channel channel)
{
_context.Channel.Add(channel);
await _context.SaveChangesAsync();
}
Check if you name properties correctly in object that you send to server, property names are case sensitive. Looks like you have in js
var customer = {name: 'foo', lastName: 'bar'};
and on server you try to deserialize your JSON to this entity
class Customer {
public Name {get;set;} //note prop names are capitalized
public LastName {get;set;}
}

Categories

Resources