Search functionality with Node JS & MySql? - javascript

I am attempting to add a search functionality with my database using Node & Handlebars to render. However when I search now it's giving me a 404 error, why is it not display search results? Here is my routing info
function searchPokemon(res, mysql, context, searchinput, complete){
var inserts = [req.body.searchinput];
var sql = 'SELECT pokemonname FROM pokemon WHERE pokemonname LIKE "%' + inserts + '%';
mysql.pool.query(sql, inserts, function(error, results, fields){
if(error){
res.write(JSON.stringify(error));
res.end();
}
context.search = results;
complete();
});
}
router.get('/search', function(req, res){
callbackCount = 0;
var context = {};
var mysql = req.app.get('mysql');
searchPokemon(res, mysql, context, req.body.searchinput, complete);
function complete(){
callbackCount++;
if(callbackCount >= 1) {
res.render('search-pokemon', context);
}
}
});
Here is my current page that I am rendering the search functionality on (pokemon.handlebars)
<h1>Current Pokemon Moves -</h1>
<table id="table">
<thead>
<th>Pokemon Name </th>
<th>Evolution Level </th>
<th>Move Name </th>
<th>Strength</th>
</thead>
<input type="text" class="search form-control" name="searchinput" placeholder="Pokemon Name">
<input type="button" class="btn btn-primary" value="Search" onclick="getUsers({{searchinput}})">
<br>
And here is my script to search
function getUsers(searchinput){
$.ajax({
url: '/search-pokemon',
type: 'GET',
success: function(result){
window.location.reload(true);
}
})
};

I had the same issue with the search function and I used typeahead.js.
Instead of 'post' I have used 'get'
router.post('/search', function(..)..
I'll put my code here, so u can get an idea.
app.js
// return homepage
app.get('/',function(req,res){
res.render('index');
});
// search function
app.post('/search',function(req,res){
var str = {
stringPart:req.body.typeahead
}
db.query('SELECT songTitle FROM song WHERE songTitle LIKE "%'+str.stringPart+'%"',function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++)
{
data.push(rows[i].songTitle);
}
res.send(JSON.stringify(data));
});
});
index.ejs
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="../JS/jquery.typeahead.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
$('input.typeahead').typeahead({
name: 'typeahead',
remote: 'http://localhost:3000/search?key=%QUERY',
limit: 10
});
});
</script>
<form method="POST" action="/search">
<label>Search Data</label>
<input class="typeahead tt-query" spellcheck="false" autocomplete="off" name="typeahead" type="text" />
</form>

Related

LoopBack v3 PUT request responding with HTTP 400

I want to display the list of record into webpage . I am using vuejs for front end development and mysql for backend .I created this applications by using LoopBack. I have some list of records inside the mysql database but the problem is when i run the web page , its does not display the records and when i want to insert new records , i am getting errors on this line ..
**(index):96 PUT http://localhost:3000/api/Account/ 400 (Bad Request)
storeAccount # (index):96
submit # VM346:3
invokeWithErrorHandling # vue.js:1863
invoker # vue.js:2188
original._wrapper # vue.js:7541**
When i clicked the index.js ,its showing error in this line
fetch(API, {...
Here is code for server.js file.
// Copyright IBM Corp. 2016. All Rights Reserved.
// Node module: loopback-workspace
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
var loopback = require('loopback');
var boot = require('loopback-boot');
var app = module.exports = loopback();
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module)
app.start();
});
Here is my html code .
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<div id="AccountApp">
<h1>Account List</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Email Address</th>
<th>Created Date</th>
<th>Updated Date</th>
<td> </td>
</tr>
</thead>
<tbody>
<tr v-for="account in accounts">
<td #click="editAccount(account)" class="accountItem" title="Click to Edit">{{account.id}}</td>
<td>{{account.email}}</td>
<td>{{account.createdAt}}</td>
<td>{{account.lastModifiedAt}}</td>
<td #click="deleteAccount(account)" class="deleteAccount" title="Click to Delete">Delete</td>
</tr>
</tbody>
</table>
<form #submit.prevent="storeAccount">
<p>
<label for="email">Email</label>
<input type="text" id="email" v-model="account.email">
</p>
<p>
<label for="createdAt">Created At</label>
<input type="text" id="createdAt" v-model="account.createdAt">
</p>
<p>
<label for="lastModifiedAt">Last Modified At</label>
<input type="text" id="lastModifiedAt" v-model="account.lastModifiedAt">
</p>
<input type="reset" value="Clear" #click="reset">
<input type="submit" value="Save User 🐱">
</form>
</div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.js"></script>
<script>
const API = 'http://localhost:3000/api/Account/';
let AccountApp = new Vue({
el: '#AccountApp',
data: {
accounts: [],
account: {
id: '',
email: '',
createdAt: '',
lastModifiedAt: ''
}
},
created: function () {
this.getAccounts();
},
methods: {
getAccounts: function () {
fetch(API)
.then(res => res.json())
.then(res => this.account = res);
},
storeAccount: function () {
let method;
console.log('storeAccount', this.account);
// Handle new vs old
if (this.account.id === '') {
delete this.account.id;
method = 'POST';
} else {
method = 'PUT';
}
fetch(API, {
headers: {
'Content-Type': 'application/json'
},
method: method,
body: JSON.stringify(this.account)
})
.then(res => res.json())
.then(res => {
this.getAccounts();
this.reset();
});
},
deleteAccount: function (c) {
fetch(API + c.id, {
headers: {
'Content-Type': 'application/json'
},
method: 'DELETE'
})
.then(res => res.json())
.then(res => {
this.getAccounts();
});
// call reset cuz the cat could be 'active'
this.reset();
},
editAccount: function (c) {
/*
This line was bad as it made a reference, and as you typed, it updated
the list. A user may think they don't need to click save.
this.cat = c;
*/
this.account.id = c.id;
this.account.email = c.email;
this.account.createdAt = c.createdAt;
this.account.lastModifiedAt = c.lastModifiedAt;
},
reset: function () {
this.account.id = '';
this.account.email = '';
this.account.createdAt = '';
this.account.lastModifiedAt = '';
}
}
});
</script>
Here is the screenshot when i run the applications .
Here is the screenshot on Networks tab ..

Delete item from nested array in Schema using moongoose

I need help with removing this item from nested array. I tried used $http.delete but this method deleted whole ObjectID from database, and second problem is that I can't connect the click on the "removing" button with backend code.
My code:
var product = new Schema({
title: String,
price: String,
description: [ObjectID]
});
Index.html
<form name="editProduct.descriptionForm" ng-submit="editProduct.updateDescription(newDescription, editProduct.descriptionForm.description.$valid)" novalidate>
<div ng-class="{ 'has-success':(editProduct.descriptionForm.description.$valid && !editProduct.descriptionForm.description.$pristine), 'has-error':(!editProduct.descriptionForm.description.$valid && !editProduct.descriptionForm.description.$pristine) || (!descriptionForm.description.$valid && descriptionForm.$submitted) }">
<div class="entry input-group" ng-repeat="item in newDescription track by $index">
<strong><input ng-disabled="editProduct.disabled" class="form-control" type="text" name="description" ng-model="newDescription[$index]" required></strong>
<span class="input-group-btn">
<a ng-click="editProduct.deleteDescription(item);" class="btn btn-remove btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</a>
</span>
</div>
</div>
<br>
<button ng-disabled="editProduct.disabled" class="btn btn-primary" type="submit">Save</button>
</form>
routes.js
router.put('/editProduct', function(req, res){
var editProduct = req.body._id;
var options = { multi: true };
Product.findOneAndUpdate({ _id: editProduct }, { $pull: { description: req.params.description }}, options, function(err, product){
if(err) throw err;
if(!product){
res.json({ success: false, message: 'Product no found' });
} else {
product.update(function(err){
if(err){
console.log(err);
} else {
res.json({ success: true, message: 'Description removed!'})
}
});
};
});
});
I also tried the following approach:
Product.findOne({'_id' : product.id}, function(err, me){
for(var i=0; i<=me.description.length; i++){
if (String(me.description[i])==String(uid)){
me.description.remove(uid);
me.save();
}
}
});
I think, the biggest problem is that I don't how to connect this function to the button.
Please try console.log(req.params.description) Before the Mongoose update query and check if the output is indeed a valid ObjectId.
If the console output is not showing the valid uid, then the problem is in the angular code. Most probably in editProduct.deleteDescription(item) function. Check if you are making Http Request by passing the correct Description Id as the parameter. Thats probably something like item.descriptionId or item.id. Debug thoroughly.

How do I render a handlebars layout in node.js from a button?

This is a really weird issue I am having.
I have a login form, this login form verifies your data and renders the Profile layout if the login is successful OR renders the register page if the login is not.
exports.logIn = function (req, res, data) {
var username = req.body.username.toString();
var password = req.body.password.toString();
connection.connection();
global.connection.query('SELECT * FROM Utilizador WHERE Nome_Utilizador = ? LIMIT 1', [username], function (err, result) {
if (result.length > 0) {
if (result) {
var object = JSON.parse(JSON.stringify(result));
var userObject = object[0];
var userQ = object[0].Nome_Utilizador;
global.connection.query('SELECT Password_Utilizador from Utilizador where Nome_Utilizador = ?', [username], function (err, result) {
console.log(result);
if (result.length > 0) {
if (result) {
var object2 = JSON.parse(JSON.stringify(result));
var passQ = object[0].Password_Utilizador;
if (password == passQ) {
console.log("Login efectuado com sucesso");
console.log(userObject);
res.render('home', { title: 'perfil', layout: 'perfil', data: userObject });
} else {
console.log("1");
}
}
} else if (err) {
console.log("asdsadas");
} else {
console.log("2");
res.render('home', { title: 'perfil', layout: 'registo' });
}
});
}
} else if (err) {
console.log(err);
} else {
console.log("Utilizador nao encontrado");
res.render('home', { title: 'perfil', layout: 'registo' });
}
});
};
This works.
And the only reason why it does work is because it comes from a FORM with a METHOD and an ACTION
<form id="login-nav" action="/login" method='POST' role="form" accept-charset="UTF-8" class="form">
<div class="form-group">
<label for="username" class="sr-only">Utilizador</label>
<input id="username" type="username" placeholder="Nome de utilizador" required="" class="form-control" name="username">
</div>
<div class="form-group">
<label for="exampleInputPassword2" class="sr-only">Palavra-Passe</label>
<input id="password" type="password" placeholder="Meta a palavra-passe" required="" class="form-control" name="password">
</div>
<div class="checkbox">
<label></label>
<input type="checkbox">Gravar Dados
</div>
<div class="form-group">
<button id="botaoLogin" class="btn btn-danger btn-block">Fazer Login</button>
</div>
</form>
However, I tried to do the same thing with jQuery, as I need to render a Handlebars layout for some products on button click,
$("#pacotes").on('click', ".produto", function () {
var prod = this.id;
console.log(prod);
$.get("http://localhost:3000/pacote?idPacote=" + prod);
});
And despite the query working and giving me the data I requested
exports.Pacote = function (req, res) {
var pacote = req.query.idPacote;
connection.connection();
global.connection.query('SELECT * FROM Pacotes WHERE idPacotes = ? ', [pacote], function (err, result) {
if (result.length > 0) {
if (result) {
var object = JSON.parse(JSON.stringify(result));
var packObject = object[0];
console.log(result);
res.render('home', { title: 'pacote', layout: 'pacote', data: packObject });
} else if (err) {
console.log(err);
}
};
});
}
It simply doesn't render the layout and I have no idea why.
What is the difference between doing a POST request like this or doing it by a form?
I don't understand why this only seems to work with forms.
I could solve it that way, but I don't think using empty forms for all my buttons would be a viable solution.
You are only making a request, you are not processing the return value:
$.get("http://localhost:3000/pacote?idPacote=" + prod);
Try changing to something like:
$.ajax({
method: 'GET',
url: "http://localhost:3000/pacote?idPacote=" + prod,
success: function(...) {...}
});

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) {
});

MongoDB array with AngularJS

I'm trying to insert data MondoDB with AngularJS's $http service , but one of the variables and the array What is in the collection , What to do ?
nome: string.
autor: string.
genero: array.
info: string.
Collection: mangas.
db.mangas.insert({nome: 'toriko', autor:'test', genero:['Ação','Aventura'], info:'...'})
Server.Js, Find mangas.
app.get('/mangas', function(req, res){
console.log('i receive a get request')
db.mangas.find(function (err, mangas){
console.log(mangas);
res.json(mangas);
});
});
Server.Js, Insert mangas.
app.post('/mangas', function (req, res) {
console.log(req.body);
db.mangas.insert(req.body, function(err, doc) {
res.json(doc);
});
});
index.html, ng-click="addManga"
<tr>
<td><input class="form-control"manga.nome></td>
<td><input class="form-control"manga.autor></td>
<td><input class="form-control"manga.genero></td>
<td><input class="form-control"manga.info></td>
<td><button class="btn btn-primary" ng-click="addManga()">Add manga</button></td> ----adiciona o metodo que se encontra no controller
</tr>
<tr ng-repeat="manga in mangas">
<td>{{manga.nome}}</td>
<td>{{manga.autor}}</td>
<td>{{manga.genero}}</td>
<td>{{manga.info}}</td>
</tr>
Controller.js
$http.get('/mangas').success(function(response) {
console.log("eu recevi a data requisitada");
$scope.mangas = response;
});
$scope.addManga = function() {
console.log($scope.mangas);
$http.post('/mangas', $scope.mangas).success(function(response) {
console.log(response);
})};
In HTML:
you should use ng-model in html to bind with controller
Like:
<td><input class="form-control" ng-model="manga.nome"></td>
instead of
<td><input class="form-control"manga.nome></td>
and in controller:
you should use $scope.manga instead of $scope.mangas because of you bind manga in html input fields.
$scope.manga = {};
$scope.addManga = function() {
console.log($scope.manga);
$http.post('/mangas', $scope.manga).success(function(response) {
console.log(response);
})};

Categories

Resources