I am using node js as my backend language. I am creating data in mongodb through submitting data using a form but I want to find the latest entered data and display it in my ejs template.
Here is my code :
/*mongoose schema setup*/
const codeSchema = new mongoose.Schema({
first: String,
second: String,
third: String,
event: String,
link: String
});
const Code = mongoose.model('Code', codeSchema);
/* GET home page. */
router.get('/welcome', async function(req, res, next) {
await Code.find({}).sort({_id: -1}).exec(function(err, data) {
if(err)
{
console.log(err);
}
else
{
//console.log(data);
res.render('index', {data: data});
}
});
});
/* GET new form form page. */
router.get('/update', function(req, res, next) {
res.render('newform');
});
/* POST update welcome page. */
router.post('/welcome', async function(req, res, next) {
const info = {
first: req.body.first,
second: req.body.second,
third: req.body.third,
event: req.body.event,
link: req.body.link
};
await Code.create(info, function(err){
if(err) {
console.log(err);
}
else {
res.redirect('/welcome');
}
});
});
The code works fine, it creates and extracts the last n record from my database but when I try to display the data in my html it does'nt shows up.I also tried using findOne() method which actually worked and displayed the last n record from my db. The problem arised when my database had no data the findOne() did'nt worked and generated error in my ejs template.
I find the data from my db using find({}) method. Like if I do First name - <%= data.first %> in my ejs template, my data does'nt show.
I also checked my mongo database which had all the information which was passed through form.
PLEASE HELP !!!!!
P.S. - I can display all the data from db using for loop but I only want to display a particular data.
Nithin K Joy here is my index.ejs
<h1>Index Page</h1>
<h4> Person1- <%= data.first %> <h4/>
<h4> Person2- <%= data.second %> <h4/>
<h4> Person3- <%= data.third %> <h4/>
<h4> Event name- <%= data.event %> <h4/>
<h4> Registration Link- <%= data.link %> <h4/>
here is my form through which recors are being submitted
<form action="/welcome" method="POST" style="width: 30%; margin: 40px auto;">
<input type="text" id="winner1" name="first" placeholder="1st">
<input type="text" id="winner2" name="second" placeholder="2nd" >
<input type="text" id="winner3" name="third" placeholder="3rd" >
<input type="text" id="event" name="event" placeholder="Event Name" >
<input type="text" id="link" name="link" placeholder="Event Regestration link" >
<button type="submit class="btn btn-success btn-block">Submit</button>
If i put my index.ejs code inside a loop it works fine but I donot want several inputs from FORM to show up in index.ejs I want only the last n record
Related
So I just started learning Node.js and I'm trying to figure out how to load more content on the button click. I think I'm either misunderstanding something or I'm confusing myself.
The code might be a bit of a mess at the moment as I've been trying a bunch of different things.
So far I have a homepage route:
//Home
app.get('/', (req, res)=> {
res.render('homepage');
});
On the homepage, I have a search bar that calls the /search route with get:
<form action="/search" method="get" id="form">
<input class="search" name="searchQuery"/>
<button type="submit">Submit</button>
</form>
Then the search route which makes a call to the API, parses the XML, renders the search page, and sends some data:
//Search
app.get('/search', async (req, res) => {
g_searchQuery = req.query.searchQuery;
const fetch_response = async (url, query) => {
try {
const response = await fetch(url);
const xml = await response.text();
xml2js.parseString(xml, (error, result) => {
var paginations = result.GoodreadsResponse.search[0];
totalResults = parseInt(paginations['total-results']);
resultsEnd = parseInt(paginations['results-end']);
g_resultsEnd = resultsEnd;
var test = result.GoodreadsResponse.search[0].results[0].work.map( w => {
let bestBook = w.best_book[0];
return {
title: bestBook.title[0],
author: bestBook.author[0].name,
image_url: bestBook.image_url[0],
small_image: bestBook.small_image_url[0],
original_publication_year: w.original_publication_year[0]._,
}
});
res.render('search', {data : {
goodReadsResponse : test,
searchQuery : query,
totalResults : totalResults,
resultsEnd : g_resultsEnd,
currentPage : g_currentPage
}});
res.end();
});
}
};
fetch_response(goodreadsapi + '?key=' + goodreadskey + '&q=' + g_searchQuery + '&page=' + g_currentPage, g_searchQuery);
});
The search page renders the data and has a load more button which with Fetch api makes a call to /search POST:
<body>
<h1>You searched for: <%= data.searchQuery %></h1>
<% if(data.goodReadsResponse) { %>
<ul class="data-container">
<%= data.totalResults %>
<%= data.currentPage %>
<% data.goodReadsResponse.forEach(function(book) { %>
<li>
<span><%= book.title %></span>
<span><%= book.author %></span>
<span><img src="<%= book.image_url %>"/></span>
<span><img src="<%= book.small_image %>"/></span>
<span><%= book.original_publication_year %></span>
</li>
<% }); %>
</ul>
<% if(data.resultsEnd <= data.totalResults) { %>
<div class="load-more__container">
<button class="load-more__button" type="button">Load More</button>
</div>
<% } %>
<% } %>
</body>
<script type="text/javascript">
window.addEventListener('load', function() {
const loadMore = document.querySelector('.load-more__button');
if(loadMore) {
loadMore.addEventListener('click', (event) => {
event.preventDefault('Load More');
fetch('/search', {
method : 'POST'
})
});
}
});
</script>
Then this is the part where I get stuck and confused. I have a app.post /search route for the load more button but I'm not sure whats the best way to pass data to that route/if I even need to.
My thinking is that I need to pass most of the data I passed through the render in /search app.get route to the app.post /search route add 1 to the current page, then append the data that I get from the API to the previous data then render the page with that updated data. But I'm slightly stuck.
Here is my repo for this, it's not 1:1 since I tried to clean some things up for the question.
Any help would be greatly appreciated,
Thank you.
let bestBook = w.best_book[0];
In the above line, Considering w.best_book is a list of books, u could just loop it and save all the books in a seperate variable, and render it when Load More button is pressed.
I have 50 different image inputs and I dont want to write them all, so
I want to use a function where I can set the parameters and only have to call the func with the parameters. Inside the ejs (html) I want to set the name attribut like this name="<% name2 %>" but if I call the func with value painting3 for name it throws
58| <% callPainting(post.paintings, paintings3, ) %>
paintings3 is not defined
I defined post in app.js
router.get('/:id/edit', async (req, res) => {
try {
const findPost = await Post.findById(req.params.id)
res.render('admin/edit', {
layout: 'layouts/admin',
post: findPost,
})
} catch {
res.redirect('/admin')
}
})
and every input should looks like this <input type="file" class="filepond" name="paintings2" value="<%= post.paintings2 %>">
So i did this, but its not working as I expected
<% function callPainting(postimage, postname, postdate, postprice, checkImage, postshowImage, name, name2, date, price, showImage) { %>
<input type="file" class="filepond" name="<% name %>" value="<%= postimage %>">
<% } %>
I got some more parameters but thats the same problem
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.
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) {
});
I'm trying to build a simple search feature, but I can't figure out why my code is not working.
This is the action that I have built to search:
search: function(req, res) {
var criteria = req.param('criteria');
var value = req.param('value');
Human.find().where({ criteria: value }).done(function(err, humans) {
if(err) {
return console.log('Error:' + err);
}else{
res.view({
title: 'Search',
humans: humans
});
}
});
}
I have a button on my main page with the ID of search. I want to make it so that whenever someone clicks my search button, it queries the database and returns the results at localhost:1337/model/search. So far, I've tried sending an ajax request to that controller action with the two variables (criteria, value) but it doesn't work.
This is the ajax call that I am submitting:
$('#search').on('click', function() {
var criteria = $('#filter').val();
var value = $('#value').val();
$.ajax({
type: 'POST',
url: 'http://localhost:1337/human/search',
cache: false,
data: {
criteria: criteria,
value: value
},
success: function(data) {
console.log('SUCCESS!');
window.location.href = 'http://localhost:1337/human/search';
},
error: function(err) {
console.log('ERROR!');
}
});
});
And this is the corresponding view:
<table>
<thead>
<tr>
<th>ID</th>
<th width="150">First Name</th>
<th width="150">Last Name</th>
<th width="150">Contact</th>
<th width="150">E-Mail</th>
<th>View</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<% _.each(humans, function(model) { %>
<tr>
<td> <%= model.id %> </td>
<td> <%= model.firstName %> </td>
<td> <%= model.lastName %> </td>
<td> <%= model.contact %> </td>
<td> <%= model.email %> </td>
<td>VIEW</td>
<td>EDIT</td>
</tr>
<% }) %>
</tbody>
</table>
Promlem #1: When you search the model like this: Human.find().where({ criteria: value }), you actually search by field named "criteria", instead of searching by field, which name is held in criteria variable.
Try to create search object like this:
var searchObj = {};
searchObj[criteria] = value;
// and then search like you did before
Human.find().where(searchObj).done(function(err, humans) {
if(err) {
console.log('Error:' + err);
// you should return some response here:
res.send(err, 500);
}else{
res.view({
title: 'Search',
humans: humans
});
}
});
Problem #2: why you do ajax request and then do redirect to the same url?
First, you make POST request, although GET request is more suitable for search pupposes. POST is usually used when you create resources.
Second, in ajax success handler, after you receive the view with found humans models, you just redirect browser to http://localhost:1337/human/search url without any parameters passed, so your controller will try to search by empty value and criteria Human.find().where({ "": "" }). So you'll not see expected result.
It's not clear whether you want to get data via ajax, or just to show it in new HTML page?
EDIT: If you don't want to use ajax, let the HTML form do the work for you:
<form action="human/search">
<input name="criteria" value="foo">
<input name="value" value="bar">
<button type="submit" id="search">Search</button>
</form>
The search button click will submit the form and pass all form data in the GET request's query string: http://localhost:1337/human/search?criteria=foo&value=bar
Of course, you can build query string manually with javascript, without using form, and redirect browser to that url. Result will be the same.