How can I create jade elements dynamically in nodejs? - node.js

I am new at coding and stuck somewhere, cause I need a bit of help. I have a basic jade template with a, h2, and div tags
h2
a(href='/'+ '#{postId}') #{title}
.content #{contentText}
and here I find and send the first title, text, and postId to my jade template
router.get('/', function(req, res, next) {
const findPost = postInfo.find({}).then((data) => {
posts.push(...data);
res.render('index' , {
title: posts[0].title,
contentText: posts[0].content,
postId: posts[0].postId
});
});
});
Now I need to create the same pug elements but the values have to come from the posts[1] array then create pug again and now values come from posts[2]. I have to do this multiple times but don't know how. Can anyone give me a tip?

I finally do it. You can send you whole array to the jade template and use your data like this:
var posts = []
router.get('/', function(req, res, next) {
const findPost = postInfo.find({}).then((data)=>
{
posts = [...data]
res.render('index' , {posts: posts});
});
});
- for(var i = 0; i<5;i++){
.content-div
h2
a(href='/'+ '#{posts[i].postId}') #{posts[i].title}
.content #{posts[i].content}
-}

Related

How to use variables from app.post in order to find and match them to database in app.get?

Hey I'm trying to use variables from my app.post in app.get but I'm getting an error that variables are not defined.
basically, I'm receiving data from API calls (when the user is submitting an input in a form),
then filtering the data to relevant data I want to display and store this data in the mongoose database.
now the problem is when I'm trying to find data in app.get from my DB and equal it to the variables from the app.post (in order to render the data on a relevant page [using ejs]) then I'm getting the error >>> asin is not define
what am I missing here? please see my code below
app.get("/", function(req, res) {
Asin.findOne({asinId:asin},function(err){
if(!err){
res.render("home");
}
});
});
app.post("/", function(req, res) {
//SOME API LOGIC//
https.get(url,options,function(response) {
//DATA RCIEVED//
response.on("end",function(){
const asinData = JSON.parse(data);
const asin = asinData.products[0].asin;
const parentAsin = asinData.products[0].parentAsin;
const category = asinData.products[0].categoryTree[1].name;
const subCategory = asinData.products[0].categoryTree[0].name;
const fbaFee = asinData.products[0].fbaFees.pickAndPackFee/100;
const newAsin = new Asin({
asinId:asin,
parentAsinId:parentAsin,
categoryId:category,
subCategoryId:subCategory,
feesId:fbaFee
});
newAsin.save(function(err){
if(!err){
res.redirect("/");
}else{
console.log(err);
}
});
Well, all I had to do is create an empty var for each const before the app.get, that way I could use the variable in both routs.

Forloop express routing in node.js

Simply: I want to do a forloop of routes with incrementing numbers in their URL since I am expecting to have around 100 entries with the same format.
Without the forloop:
app.get('/day1', (req, res) =>{
res.render('pages/day1/day1.ejs')
});
app.get('/day2', (req, res) =>{
res.render('pages/day2/day2.ejs')
});
app.get('/day3', (req, res) =>{
res.render('pages/day3/day3.ejs')
});
I've tried this forloop:
for(i=1; i<4; i++){
app.get('/day' + i.toString(), (req,res) =>{
res.render('pages/day'+ i.toString() +'/day' + i.toString())
})
};
This forloop "works", but only for the last pass of the forloop (in this case for '/day3').
In this scenario:
For '/day2' and '/day1' I get a "Cannot GET /day2" or "Cannot GET /day1".
Even worse, if I try to play around with the initial parameters of the forloop, let's say (i=2;i<3;i++), I get weird behaviors like the /day3 link redirecting me to the /day4 link when it should not even be included.
Does this have something to do with my browser cache history?
You are following wrong apporch,
here, by Changing Route to somthing like this,
app.get('/day/:id', (req, res) =>{
let day = req.params.id
// use the template string
res.render(`pages/day${day}/day${day}.ejs`)
});
api call will be ( just example if you are using axios at client side ),
API_URL will be your backend app url,
axios.get(`${API_URL}/day/1`)
you will get desired output according to your need.
No sane person loops routes like this. You'd want to employ dynamic routing like this:
app.get('/:day', (req , res) => {
const { day } = req.params
res.render(`pages/${day}/${day}.ejs`)
})
If you truly want to do it your way, you could try building an array first like this:
const days = []
for (let i = 0; i < 100; i++) {
days.push("day" + i.toString())
}
Then build the routes:
days.forEach(day => {
app.get("/" + day, (req, res) => {
res.render(`pages/${day}/${day}.ejs`)
})
})

Empty result when querying MongoDB database in Node.JS

I appologise for the horrendous title for this submission but I have been tearing my hair out for at least 8 hours now trying to solve this.
I initially took some guidance from sova's result on Express displaying mongodb documents in Jade Express displaying mongodb documents in Jade
However whenever I try and do the query it fails.
my index.js code is this.
app.get('/test', function (req, res) {
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost/quizmaster';
var results_from_mongo = [];
MongoClient.connect(url, function (err, db) {
var str = db.collection('qmquestions').find();
str.each(function (err, doc) {
//console.log(doc);
results_from_mongo.push(doc);
console.log(results_from_mongo) //Push result onto results_array
});
//now we have a results array filled like this:
// results_from_mongo = ["some string", "some string", "some string"]
//so let's pass them to the jade file to render them.
res.render('test', {results_from_mongo : results_from_mongo });
});
});
My test.jade code is this
block content
h1= title
h2= "results from mongo:"
select
each results_from_mongos, i in results_from_mongo
option(value=i) #{results_from_mongos}
I have even tried the pug variation of this (test.jade)
table
thead
tr
th Question name
th Question
th Answer
tbody
each results_from_mongo, i in results
tr
td= results_from_mongo.questionTitle
td= results_from_mongo.question
td= results_from_mongo.answer
The db.collections.find direct from MongoDB result is
{ "_id" : ObjectId("58af574c4fef02081c32da2f"), "question" : { "questionTitle" : "Test", "question" : "Test", "answer" : "Test" } }
I have just tried so many different ways of trying to get it but all it equals is an empty result no matter what I do if anybody could help me out on this I would be greatly appreciated as I am just ripping my hair out on this and I feel it must be something so simple which I am missing. If anymore code is needed then I will edit the post with the code asked for.
Your index.js seems to be incomplete, but the biggest issue was that you didn't have a callback for the .find() call for mongo. Looking at the docs - https://www.npmjs.com/package/mongodb - it seems as though they use .toArray() which takes a callback. You need to place your res.render inside of that callback so that it gets executed after mongo returns results.
As of now you are executing res.render() when mongo hasn't gotten any data yet, due to the asynchronous nature of node.
index.js
const express = require('express')
const app = express()
var MongoClient = require('mongodb').MongoClient
app.set('view engine', 'pug')
app.get('/test', function (req, res) {
var url = 'mongodb://localhost/quizmaster';
//var url = 'mongodb://localhost:27017/quizmaster';
var results_from_mongo = [];
MongoClient.connect(url, function (err, db) {
//var str = db.collection('qmquestions').find();
var str = db.collection('qmquestions').find({}).toArray(function (err, docs){
if(err){
return res.send('error')
}
console.log(docs)
//return res.render('test', {results_from_mongo : results_from_mongo });
return res.render('test', {results_from_mongo : docs });
})// callback
//str.each(function (err, doc) {
// //console.log(doc);
// results_from_mongo.push(doc);
// console.log(results_from_mongo) //Push result onto results_array
//});
//now we have a results array filled like this:
// results_from_mongo = ["some string", "some string", "some string"]
//so let's pass them to the jade file to render them.
});
});
app.listen('3030', function(){
console.log("listening on 3030")
})
views/test.pug
block content
h1= title
h2= "results from mongo:"
select
// each results_from_mongos, i in results_from_mongo
each results_from_mongos, i in results_from_mongo
option(value=i) #{results_from_mongos}
ul
each item in results_from_mongo
li= item.question.questionTitle
Use the method toArray After your find method call. As This:
collection(...).find().toArray(function(err,doc)=>
//Do what you want
)

Restrict Knex query on Bookshelf model to return only n records

I have the following code where I am using the splice function to pass only the first 10 /JSON objects to the JADE template.
app.get('/index', function(req, res) {
new models.Condos()
.query('orderBy', 'age', 'asc')
.fetch()
.then(function(names) {
var name = names.splice(0,10);
res.render('index', {
names: name.toJSON()
});
});
});
};
Is there any way where i could restrict the query itself to return only the first 10 records instead of splicing the array to do that (use the offset and limit parameters) ?
You can write a knex query to achieve this it will look something like:
app.get('/index', function(req, res) {
knex.select('*')
.from('condos')
.limit(10)
.then(function(names) {
res.render(names);
});
});
You will also need to require knex in your router file.
What I was looking for was something more along these lines.
app.get('/index', function(req, res) {
new models.Condos()
.query('orderBy', 'age', 'asc')
.query('limit','10')
.fetch()
.then(function(names) {
var name = names.splice(0,10);
res.render('index', {
names: name.toJSON()
});
});
});
};
You can use the Pagination plugin from Bookshelf.
models.Condos.fetchPage( {page:1, pageSize:10} )
Note: for the first page if the page size is 10, you can leave out the params and just
models.Condos.fetchPage()

How can I retrieve values from the uri in express js?

Hello I want to retrieve a value from the uri and use it in my code, for example what would you do if you had something like http://mysite.com/uri1/uri2 and you wanted to get only uri2 ?
app.get("/:uri/:id", function(req, res) {
var uri = req.params.uri,
id = req.params.id;
// do code
});
To clarify :uri and :id are named url segments.
The following with also work
app.get("/rooms/:roomId", function(req, res) {
Rooms.get(req.params.roomId, function(err, rooms) {
res.render("rooms/index", { rooms: rooms });
});
});

Resources