Jade block extend for each item in database? - javascript

What am I doing wrong?
test.jade
doctype !!! 5
html(lang="en-us")
head
title test
h1 Information;
body
block testcontent
form(method="post")
input(type="button", value="refresh")
testcontent.jade
extends test
append testcontent
br
p test #{title}
routing handler;
app.get('/search', function(req, res) {
res.render('test');
});
app.post('/search', function(req, res) {
table.find().sort({created:1}).toArray(function(err, items) {
if(err) {
console.log(err);
}
else {
res.render('testcontent', {title:items._id});
}
});
});
Trying to make it write 'test' and the title for each item in my database. I click 'refresh' in the page, nothing happens.
When the user sends a POST using the refresh button, it's meant to get every entry's _id in my database and stick it in an array with table.find().sort({created:1}).toArray()
Then I wanted it to render testcontent for each entry, res.render('testcontent', {title:items._id}); which should push out several entries of "test exampleTitle" on new lines.
Then that goes into the testcontent block in the first file, which can now be 'updated' every time the user clicks refresh.
Right?
But it doesn't work, no errors thrown, it just doesn't add the "test title" text to the /search route like I want it to.
I'm using Node.js/express and MongoDB.

Did you check if your form is submitted? Change the type of the button to submit from button and that will submit the form. And in your route handler, I see you are passing only one title to your template, so you will see only one line in your page. If you want one line per entry, you should pass the whole array to your template and iterate using the 'each' construct in your jade template

Related

How to retrieve data in front end from res.send and create page for each element in DB dynamically

I've got a variable, say data containing data in the form of an Array with each item having a unique ID.
app.get('/products/:id', function (req, res) {
res.send(data.map(data => "" + data.id + "")) //basically gets the data of the element in the Array whos Id has been given to the server.
})
I have sent the data from the server to the front-end on a GET request. But how do I create a seperate webpage for each element dynamically in the data array? where do i have to write the html and the css? I want a way with which I can create a page for each element like domain.com/products/id which displays information about the data entry which matches the Id . Do need to use pug? hbs?ejs? I' so confused.
So I found I had to use Javascript Templates to send data to a view. I used ejs, which went pretty good!
Here's how it went:
1. fetch my data form my DB, which in this case is MongoDB using db.findOne().
2. We get an array, let's say data. send the variable to my view using the same res.render syntax, just in a cooler way.
app.get('/blogs/:id',(req,res)=>{
const data = //find function
res.render('page.ejs', {body:data});
})
:id creates a page for every element in the DB.
and now the view that is, the public/page.ejs file has a global body variable, which
we can now use to show our blogs.
3. the front end markup in pages.ejs:
<div class="blogs">
<%=body.forEach (item)=>{%>
<p><%=item.blog%></p><br>
<%=}%>
</div>
We call a forEach function on the array, and create a paragraph element for each item in the array, that is for each blog.
Please not that <%, <%= and %> are EJS' tags. Read about them more in the official docs.
Thanks Mohammad for letting me know about this. (From comments)

How to submit data then post on another page mongoDB/Node.js

I am needing to have 1 page of a website submit data to MongoDB then pull that same data and display it on a different page. I am using node.js, express, Mongoose, and MongoDB.
Currently, I have it so It gets submitted properly to the database, and I can see it with the correct layout, But I cannot seem to get it posted on the page.
How exactly do I go about doing this?
Can someone give a example of code of this?
I am really new to this stuff and still learning.
Thanks!
In the route of the page you want to load, use the Mongoose .find()
method.
You can use {} in the find() method to return all the data, or access
individual data based on the object key find({id:'value'}). Then when you
render the page, just pass in an object to the render, where the key is
what you access in the url page, in my example you would use
(mongs) to access the values within the url page (.ejs, etc). So in
your route definition file:
app.get('/', (req, res) => {
MongModel.find({}, (err, foundMongModel) => {
err ? console.log(err) : res.render('url/route', { mongs: foundMongModel });
});
});
Then if you're using .ejs file, you would need to use <%= %> to access
individual data, and <% %> to use a loop or something.
and use the mongs value. So if you imported all the data from the
database, you could loop through it using
<% mongs.forEach(mong =>{ %>
<div>mong.key<div>
<% }) %>
You can access the keys for each database object like above using
mong.key

How Do I Implement a Seach Filter on a Database Query and Refresh the Page with Javascript/PHP

I'll try to simplify this as best as possible. I have a site written in PHP/JavaScript. When I go to a certain page it by default displays a set of filter buttons at the top of the page and an unfiltered data result below that. I can successfully capture the filter results entered and create the appropriate query. My problem is that I don't know how to pass the query back to the database to requery/refresh the data below the filter boxes. The pages are setup as follows:
The page I navigate to is Search.php. In the document.ready script it calls a loadsearchtable function.
$(document).ready(function() {
/* Load Search Table */
LoadSearchTable(SearchString, FilterString);
Initially the searchstring and filterstring are empty. The LoadSearchTable function calls another page to load the results of the original query:
$('div#PostingTable').load('ajax/SearchTable.ajax.php',{SearchString:SearchString,FilterString:FilterString},function(response,status,xhr){
The SearchTable.ajax.php page runs the database query and populates an unordered list with the results.
The body of the Search.php is the following code which opens the page which displays the filters and the unorderedlist populated above:
<body>
<?php BodyShell($FileArray,$User,'pages/Search.pages.php'); ?>
</body>
The javascript on the search page captures the button click on the Search.pages.php. From this I can get what has been entered in the filters but I don't know how to re-call the loadsearchtable function to go through this process again to change what is displayed in the SearchTable.ajax.php unordered list.
I hope this is clear. If not, please let me know what you need from me to explain it better.
As requested below:
After I build my filter I have the following code:
$("div#AJAXDiv").load('ajax/SessionVariable.ajax.php',{VarName:'SearchString',VarValue:$(query)},function(response,status,xhr){
if (status!="success")
{
/* error with ajax call */
}
else
{
if(response)
{
/* Ajax call ok, php script has issues */
alert(response);
}
else
{
/* ajax and php script complete succesfully */
window.location = "Search.php";
}
}
});
This sets a session variable and then calls another instance of itself "Search.php". This time the session variable is populated which should then pass into the LoadSearchTable(SearchString, FilterString) function. However I'm not getting:
1. Any errors
2. Any change in the data that would indicate that the filter has been applied. I've checked the $query prior to populating the session variable and it is correct. I've put alerts within the session variable function (there not all shown above) but am not getting anything and I'm not getting any errors. Just nothing.

How to programmatically add items from a page in KeystoneJS

I'm trying out KeystoneJS to build a site in which people can submit words and ask other users for synonyms. So I've build a simple Word model:
var keystone = require('keystone');
var Types = keystone.Field.Types;
var Word = new keystone.List('Word', {
map: { name: 'word' }
});
Word.add({
word: { type: Types.Text, required: true, initial: "New word", index: true }
});
Word.defaultColumns = 'word';
Word.register();
The idea is that a user enters a word in an input box on the homepage, clicks "Submit," and the word gets added as an item in the Word model. But I can't figure out the interplay between the Javascript on the page that handles the event that fires on clicking "Submit" and the code that actually creates a new items in the DB, like so:
var keystone = require('keystone'),
Word = keystone.list('Word');
var newWord = new Word.model({
word: newWord // read from the input box on the home page
});
newWord.save(function(err) {
// post has been saved
});
I originally naively supposed that I could make Word part of the locals object and create the new item from the JS that lives on the page, but this doesn't work. So I imagine I need to read the word from the input box, then make an AJAX call to a route that saves the word to the DB. Here is where my understanding of KeystoneJS breaks down. Where would I put the code to accept that AJAX call and create the new item?
The javascript in the page, and keystone on the server side are indeed two seperate domains. To interact with keystone from your page you have to make HTTP calls. These calls are routed to keystone views.You can find an example in de keystone demo site:
in keystone.js the routes are set:
keystone.set('routes', require('./routes'));
in routes/index.js the routes are defined, ie:
app.get('/blog/:category?', routes.views.blog);
In the example above the url "/blog/news" is handled by the view routes.views.blog, and "news" is an (optional) parameter.
In your case you would end up (if you want you use REST style) with something like:
app.post('/word/:newword?', routes.views.word);
The .post method routes urls to this view if and only if the request is a POST request.
The solution that you suggest, making a AJAX call is one of the possible solutions.You could also use a form and post the whole page.
Within the view you create a handler for the view like this:
view.on('post', function(next){
if (req.params.newword){
//store and create answer
next();
}
});

Dynamically set href anchor tags not sending a get request

I'm not really sure where I"m screwing up with this. Basically I'm reading from my database to generate an html page and dynamically set the hrefs of some anchor tags. When I click on the links, however, the page just reloads and doesn't send a GET request to the server. The important part of the Jade rendering is here.
each val in tournaments
a(href="/home/tournaments/?_id=" + val._id)
The _id param is just the default _id MongoDB gives to the document upon creation.
I'm also using Express to handle my server side requests. The pertinent one for this is here:
app.route("/home/tournaments/:id")
.get(function(req, res, next) {
console.log("Request: " + req.query._id);
});
Nothing gets printed to the console when I click the anchor tag, so I guess it's not reaching this route for some reason.
Can anyone explain what I'm doing wrong and what I need to do to fix it?
Thanks in advance.
The problem is that you're placing the ID in the query string instead of the actual url path. So to make your existing route match, you'd need to instead do this:
each val in tournaments
a(href="/home/tournaments/" + val._id)
and then use req.params.id instead of req.query._id.
OR you could adjust your route pattern to just be /home/tournaments.

Categories