Display data in Jade with Mongoose - node.js

I've been trying to grab my data that's stored in mongodb and display it with a simple Jade template. I'm kinda new to this and I'm totally lost at this point.
Here's my output when I render my collection on /yfirlit
The express router for /yfirlit looks like this
apiRouter.get('/yfirlit', function(req, res){
apiUser.find(function(err, users) {
if(err) res.send(err);
res.render('yfirlit', {title: 'Yfirlit', users: users});
});
});
My simple Jade Template
html
head
title!= title
body
div #{users}
p
| API
When I run the test the whole mongodb collection is displayed on the site. What I'm looking for is to be able to display only a portion of the documents in the collections. For example: I tried to display only the name property in the Jade template but was unable to get it right.
html
head
title!= title
body
div #{users.name}
p
| API
Any help would be greatly appreciated, I'm so lost and I would love to be able to render out only the properties that I wanted instead of the whole thing like in the picture.
Cheers!

As Sgnl said, within the route you'll need to render the Jade view and include the data just like you have, but by using res.render:
apiRouter.get('/yfirlit', function(req, res){
apiUser.find(function(err, users) {
if (err) return next(err);
res.render('index', {
title: 'yfirlit',
users: users
})
});
});
...And I think you'll also need a loop to display the data from within your Jade view, because it contains multiple values:
if users
each user in users
div #{user.name}

Related

How to get specific document from CouchDB and to exports it in Jade view?

I need to get the URL and according to it do display specific document from CouchDB in Jade view.
router.get('/jobs/:name', function (req, res, next) {
couch.get(dbName,viewURLSpecific).then(function(data,header,status){
var name=req.params.name;
console.log(name);
res.render('detailedjobs',{name:data.data.rows});
},
function(err){
res.send(err);
});
``` jade view
.row
.col-xs-12.col-sm-8
.row.list-group
each detail in the name
.col-xs-12.list-group-item
h4
p #{detail.value.name}
small
p #{detail.value.location}
.col-xs-12.col-sm-4
p.lead= sidebar
The view renders every document in my employer database. But I need to render the only a specific document, based on the name of the document, which is got from URL.

How to show all data and filter one in mongoose and mongodb?

I'm trying to get all the data out of mongo database, but i want to filter one specifically.
What i'm trying to do is. Get someone to click on my portfolio to show them details about what i created. But on left sidebar i want to show other work that i've done. Check pictures and you should understand better.
router.get('/portfolio/:id', function(req, res, next) {
Work.findById(req.params.id, function(err, foundWork) {
console.log(foundWork)
if (err) {
console.log(err);
} else {
res.render('portfolio', {
title: 'Portfólio',
work: foundWork
});
}
});
});
Picture
FindById only showing the result of one specific project.
Thanks for your help
EDITED-----------------------------------------------------
So i changed the code to get all data from DB and filtered item that i need by id. I can't parse the data through to ejs. When i console.log data in nodejs i get data. When i console log in ejs i get undefined.
Here is the pic what i get in nodejs.
Console.log
I noticed when i loop through the filtered item i get all data i need. I dont think it's right to loop through data when i'm onlz parsing one item to ejs.
So i figured this out myself.
I did as the user givehug said. It worked but then i had to loop through the filtered items again in ejs despite there is only one item. EJS doesnt know how many items as left in filtered array so i looped through. Got one item out and then i rendered it and it worked.
you have to add a new property to your schema to classify your work. for example,
in your schema:
{workType:{type:String}} //either required or no
when you post your data, add this property too
{workType:"other"} //i just made it up
query like this:
const other=await Work.find({workType:"other"})
now you will get the data that u need.

Expressjs (node) - How to get a set of data which is filtered according to the user

I am new to express js. I am currently building a todo list web app. I have been following the tutorials and is able to perform basic CRUD operation. I have two models.
Users - (name, email, password hash, password salt, todo_items - which reference to the second model).
Todo_items - (title, description, due_date, user - which reference to the first model).
When a user log in, I am able to read his user_id. However, how can i filter the todo_items that only belongs to the user? My current code looks like this and is returning all the todo_items from all the users.
router.get('/api/todo_items', function(req, res, next){
Todo_items.find(function(err,todo_items){
if(err){return next(err); }
res.json(todo_items);
})
});
Currently, I am using a front end framework, Angularjs to filter the results that get displayed. But I thought this is inefficient as the user base gets big. How do I create a filtering system from the backend?
You can query the collection on the user field, assuming it references the User model on the _id field so you could have something like the following:
router.get('/api/todo_items', function(req, res, next){
Guest.find({ "user": user_id }).exec(function(err, todo_items){
if(err) { return next(err); }
res.json(todo_items);
});
});

NodeJS: Dynamic form

How do I create a dynamic form with NodeJS, Express and Mongoose?
Right now my contents are hardcoded for the sake of the question.
This is how my page creation looks like:
app.post('/create', function(req, res) {
var page;
var b = req.body;
page = new Page({
title: b.title,
url: '/' + Func.stringToUrlSlug(b.title) + '/',
headline: b.headline,
contents: [{
body: b.content1_body,
class: 'CLASS1'
},{
body: b.content2_body,
class: 'CLASS2'
},{
body: b.content3_body,
class: 'CLASS3'
}],
border: b.border,
target: b.target,
hidden: b.hidden,
externUrl: b.externUrl,
order: 700
});
page.save(function(err, page) {
if (!err)
res.send(page);
else
res.send(err);
});
});
And my Jade frontend creation:
....
div
label Content
textarea(name='content1_body')
div
label Content
textarea(name='content2_body')
div
label Content
textarea(name='content3_body')
....
And my mongoose schema contents are of Array type.
My question here is: How can I have these documents to being dynamic in my route depending on how many extra content fields I add?
Do I need to push these extra fields inside my page array somehow?
Say if something is unclear. Thanks in advance.
There are multiple approaches how to implement "dynamic forms". The easiest would be using the single page application features that you do not load the page at all when you move between the forms. The result could be stored in document.localStorage and when the user has finished send the results to server.
When you do not use the client side possibilities, you have to store the each form results in temporary database "table/document", also you have to keep track on what form the user is. When user reaches end, insert all the data from previous steps to table/document.
Alright after aaaaa lot of trying I solved it myself.
I ended up creating my form elements that should be dynamic this way:
div
label Class
input(name='content[1][class]')
label Content
textarea(name='content[1][body]')
div
label Class
input(name='content[2][class]')
label Content
textarea(name='content[2][body]')
....
That way I could reach the content fields, wether it was the class or the body field. And I ended up pushing these into my page array:
b.content.forEach(function(item) {
page.contents.push({ class: item.class, body: item.body });
});
I end up adding more form fields with jQuery.
If you enable the extended parsing of the Express body-parser
var app = express();
...
app.use(bodyParser.urlencoded({ extended: true }));
Express will use the qs library. This library has automated parsing for converting query parameters to array or objects.
Example (source: qs docs)
var withIndexes = qs.parse('a[1]=c&a[0]=b');
assert.deepEqual(withIndexes, { a: ['b', 'c'] });
After correctly parsing your inputs, it's a matter of sending this info to mongoose.

Variables not showing content on Jade template

I am learning Node.js using a book. There was an example that as a learning experience I converted from what it was to a SQL version of it.
This single page is only intended to display user information. I load the user information on a middleware then pass it to the Jade template. Everything working up to this point.
When I want to render the template below, wherever I user content from the user object, it renders nothing.
h1= user.Name
h2 Bio
p= user.Bio
form(action="/users/" + encodeURIComponent(user.User), method="POST")
input(name="_method", type="hidden", value="DELETE")
input(type="submit", value="Delete")
To check if the object was without content, I added this 2 lines on the front
-console.log ( 'Inside Jade' )
-console.log ( user )
and the result in the console is:
Inside Jade
[ { Name: 'Jennifer Lopes',
User: 'jenny',
Password: 'asd',
Bio: 'Actress and singer' } ]
So this tells me that the information is there, but is not being rendered.
The code used to render the template is:
app.get ('/users/:name', loadUser, function ( req, res, next ) {
res.render ( 'users/profile', { title: 'User profile', user: req.user });
});
Can you please help me to understand what am I doing wrong? Thanks in advance.
A little hard to tell without seeing all your code, but per the output of your console it looks like user is actually an array of objects based upon the brackets, if you change your jade template to output something like user[0].Name does it give you your expected values?

Resources