Use ng-repeat ( AngularJS) with EJS and express - javascript

Is it possible to perform Angular operations such as ng-repeat within the EJS templating engine for the purpose of TWO WAY DATA BINDING?
If so, can you provide an example of how to pass an array from express to EJS and perform ng-repeat.
My User Schema:
var mileSchema = mongoose.Schema({ miles: String });
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
},
userInfo : {
fullname : String,
region : String,
},
milesLog : [mileSchema]
});
module.exports = mongoose.model('User', userSchema);
My Express Route:
var User = require('../app/models/user');
app.get('/profile', isLoggedIn, function(req, res) {
res.render('profile.ejs', {
user : req.user
});
});
My EJS template: ( this is only a section of the whole template )
<p ng-repeat="m in milesLog">{{m}}</p>
<% if (user.local.email) { %>
<p>
<strong>id</strong>: <%= user._id %><br>
<strong>email</strong>: <%= user.local.email%><br>
<strong>Region</strong>: <%= user.userInfo.region %><br>
<strong>username</strong>: <%= user.userInfo.fullname %><br>
</p>
<% } %>

Related

How to get the aggregated data from mongodb to display in ejs?

So I'm making a simple forum app and I have 2 collections:
User
_id:60ccb13a21d65f0c7c4c0690
username: testuser
name: test
And Createpost
_id:60d80b1305dcc535c4bf111a
postTitle: "test post"
postText: "aaaaa"
postUsername: "testuser"
If I wanted to get data of testuser from User displayed on his forum post, what would be the best way to do that? This is what I've tried so far:
router.get('/forum', async (req,res)=>res.render('forum', {newPost: await Createpost.find().sort({ date: 'desc'}),
postUser: Createpost.aggregate([{$lookup: { from: "User", localField: "postUsername", foreignField: "username", as: "user"}}])}));
Then I want to get the name field from the newly joined documents in EJS like here:
<% newPost.forEach(newPost => { %>
Posted by: <%= newPost.postUsername %> - Name: <%= postUser.name %>
<%= newPost.postText %>
<% }%>
But when I do this, it doesn't say anything, or if I only put postUser, it says "[object Object]". Any help would be much appreciated.
You are missing await in your postUser query. So the return of this query can be a promise. I edited it a bit and just made 1 query to get all the data
you needed.
router.get('/forum', async (req, res) => {
const newPosts = await Createpost.aggregate([
{
$lookup: {
from: 'users',
localField: 'postUsername',
foreignField: 'username',
as: 'user'
}
},
{
$unwind: '$user'
}
]);
res.render('forum', {
newPosts
});
});
newPosts will have a value like this:
[{
"_id" : "60d80b1305dcc535c4bf111a",
"postTitle" : "test post",
"postText" : "aaaaa",
"postUsername" : "testuser",
"user" : {
"_id" : ObjectId("60ccb13a21d65f0c7c4c0690"),
"username" : "testuser",
"name" : "test"
}
},...]
Ejs file should be like here:
<% newPosts.forEach(newPost => { %>
Posted by: <%= newPost.postUsername %> - Name: <%= newPost.user.name %>
<%= newPost.postText %>
<% }%>

Passing MongoDB Data into .ejs-Template with Node.js Express

I think i clicked myself through thousands of tutorials but i'm still stucked at this point: I want to render all the data, which my express-app is writing into mongodb at its start, into embedded javascript. I would like to have a simple table which is showing all the data from mongodb. It shall also always get the actualized Data when calling the route.
My first idea was, to save the data in an array. Pass it to the .ejs file. Create a table, iterate through my data-array and write it in. My problem is, that i can not write the data into an array after calling the find()-Function.
The model subscriber.js:
const mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var subscriberSchema = mongoose.Schema({
nr: Number,
mailIdent: {
type: String,
unique: true
},
from: String,
emails: {
type: String,
default: ''
},
text: String,
uLink: String,
anwalt: Boolean,
create_date:{
type: Date,
default: Date.now
}
});
subscriberSchema.plugin(uniqueValidator);
var Subscriber = module.exports = mongoose.model('Subscriber', subscriberSchema);
I'm really new to the topic and it feels like i'm just messing around. Please help
//get Subscriber
/*module.exports.getSubscribers = Subscriber.find(function(err, subs){
if(err) return console.error(err);
console.log(subs);
});
*/
module.exports.subscriber = Subscriber;
module.exports.getSubscriberByID = function(_id, callback){
Subscriber.findById(_id, callback);
};
module.exports.getSubscribers = function(){
var subscribers = Subscriber.find({});
return subscribers;
};
Then i want to pass it with my app.js to the index.ejs:
app.get('/', function(req, res){
var subs = Subscriber.getSubscribers().toArray();
console.log(subs);
res.render('index',{subs: subs} );
});
I know, that my .ejs still seems a little simple. But so far it shall be just functional:
<!DOCTYPE html>
<html>
<head>
<link href="/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<% include partials/nav.ejs %>
<h1>Welcome to the Database</h1>
<p>You won't find more Information than here!</p>
<p>Table</p>
<table>
<colgroup span="5" class="columns"></colgroup>
<tr>
<th>Nr</th>
<th>Name</th>
<th>Mail</th>
<th>uLink</th>
<th>Anwalt</th>
</tr>
<% for (var i = 0; i<subs.length; i++) { %>
<tr>
<td><%= subs[i].nr</td>
<td><%= subs[i].name</td>
<td><%= subs[i].email</td>
<td><%= subs[i].uLink</td>
<td><%= subs[i].anwalt</td>
</tr>
<% } %>
</table>
</body>
</html>
The following is from mongoose docs:
Query#find([criteria], [callback])
When no callback is passed, the
query is not executed. When the query is executed, the result will be
an array of documents.
You can use a callback just Like you do with getSubscriberByID function, here is an example:
subscriber.js:
...
module.exports.getSubscribers = function(cb){
Subscriber.find({}, cb);
};
app.js
app.get('/', function(req, res){
Subscriber.getSubscribers( function (err, subs) {
if (err) throw err;
// else render result
res.render('index', { subs: subs} );
});
});
here is ur app.js code..
app.get('/', (req, res) => {
// db.collection('story').aggregate([
// { $lookup:
// {
// from: 'story_content',
// localField: 'ObjectId("5a322e1130cb6225a086f37d")',
// foreignField: "5a322e1130cb6225a086f37d",
// as: 'joinstorydata'
// }
// }
// ]).toArray(function(err, res) {
// if (err) throw err;
// console.log("********************************************************")
// console.log(res);
// final=res;
// });
db.collection('bid_placement').find().toArray((err, docs2) => {
if (err) return console.log(err)
// renders index.ejs
lnames2 = [...new Set(docs2.map(a => a.bid_location))]
lnames2.sort();
res.render('index.ejs', {
//story12 : docs1 ,
//story_content: final,
storylocation : lnames2
});
});
});
and here is ur html code
<select name="Courses" id="Courses">
<% for(var i=0; i<storylocation.length; i++) {%>
<option value="<%= storylocation[i]%>"> <%= storylocation[i]%> </option>
<% } %>
</select>
you can use it like <%= storylocation[i].abc%> .. put you desire data instead of abc on each column of table...
It was driving me mad and finally i found out. I did not closed the Javascript in the .ejs file. That was definetly the most stupid misstake ever

Display to client only if collection exists on mongoDB Node JS

I have this schema model defined on Mongoose:
var mongoose = require("mongoose");
var IngredientSchema = new mongoose.Schema({
name:String,
number:Number,
exist:Boolean,
photoName:String
})
module.exports = mongoose.model("Ingredient", IngredientSchema);
And I want to display on a web page a different result depending on whether there is an Ingredient already created on database or not.
Here's what I tried so far (but it doesn't work):
<!-- Check if inventory is empty or not, and display accordingly -->
<% if ( ! ingredients) { %>
<p>Add you first ingredient to the inventory !!</p>
<% } else { %>
<% ingredients.forEach(function(ingredient) { %>
...
...
And here's my route:
// Index route
app.get("/inventory", function(req, res) {
Ingredient.find({}, function(err, allIngredients) {
if (err) {
console.log(err);
} else {
res.render("inventory", { ingredients:allIngredients });
}
})
})
Thank you very much for your help.
Just check the length of ingredients array:
<!-- Check if inventory is empty or not, and display accordingly -->
<% if (!ingredients.length) { %>
<p>Add you first ingredient to the inventory !!</p>
<% } else { %>
<% ingredients.forEach(function(ingredient) { %>
...
...

Node.js cant log Class model data from Student model

I am having an issue here. I currently am making a school directory using node.js and MongoDB. I am in an app.post request and for some reason I can't get the name of the class being linked to the student to log to the console, but createdClass.name will print...
Here is the code...
app.post("/students/:id", function(req, res){
Student.findById(req.params.id, function(err, foundStudent){
if(err){
console.log(err);
} else {
Class.create(req.body.class, function(err, createdClass){
if(err){
console.log(err);
} else {
createdClass.student.id = foundStudent._id;
createdClass.student.name = foundStudent.name;
console.log(createdClass);
createdClass.save();
foundStudent.classes.push(createdClass);
console.log(foundStudent.classes[0].name);
foundStudent.save();
}
});
}
});
res.redirect("/students/" + req.params.id);
});
Also, here are my models...
STUDENT:
var mongoose = require("mongoose");
var studentSchema = new mongoose.Schema (
{
name: String,
classes: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Class"
}
],
grades: Array
}
);
module.exports = mongoose.model("Student", studentSchema);
CLASS:
var mongoose = require("mongoose");
var classSchema = new mongoose.Schema (
{
name: String,
student:
{
id:
{
type: mongoose.Schema.Types.ObjectId,
ref: "Student"
},
name: String
}
}
);
module.exports = mongoose.model("Class", classSchema);
Thank you in advance and please do let me know if there is anything I can add to make this easier to read.
Here is the page making the post request...
<div>
<h1>Student Profile</h1>
<h2>Name: <%=student.name%></h2>
<div>
<h3>Classes:
<form action="/students/<%= student._id %>" method="POST">
<%if(student.classes.length === 0){%>
<p>No classes linked to profile, please add class..</p>
<input type="text" name="class[name]" placeholder="Class name">
<% } else { %>
<% student.classes.forEach(function(course){ %>
<li><%= course.name %></li>
<% }); %>
<% } %>
</form>
</h3>
</div>
</div>
Class is a reserved word and can't be used for a variable

Sails.js - Creating a view to edit a model

I have a simple model as follows:
module.exports = {
attributes: {
firstName: 'STRING',
lastName: 'STRING',
contact: 'STRING',
email: 'STRING'
}
};
I already have an index action that displays all the humans. This is the corresponding view:
<h1>List of all humans</h1>
<ul>
<% _.each(humans, function(model) { %>
<li><%= model.firstName %> /// <%= model.lastName %> /// <%= model.contact %> /// <%= model.email %> <button id="<%=model.firstName %>"type="button">Edit</button> </li>
<% }) %>
</ul>
What I want to accomplish is that every time someone clicks on the EDIT button, to display a view containing all the information of that specific model (localhost:1337/human/edit/:id). How can I write my controller? How can I tell my controller that I want THAT specific model to be displayed and route it properly?
Thank you!
You should point browser to localhost:1337/human/edit/:id url, where :id is your particular model's id. For example
<ul>
<% _.each(humans, function(model) { %>
<li><%= model.firstName %> <button id="<%=model.firstName %>" type="button">Edit</button>
</li>
<% }) %>
</ul>
This will automatically execute Human.edit controller with id param set to particular model's id. You don't have to write any custom routes, this is default behaviour.
Example of Human/edit controller action:
edit: function(req, res) {
Human.findById( req.param('id') )
.done(function(err, human) {
if (err) {
return res.send(err, 500);
} else {
if (human.length) {
res.json(human[0]);
} else {
res.send('Human not found', 500);
}
}
});
}
Here I return model encoded as json in response, for simplicity, but you can use your view.
In addition, firstName property is not the best value to use as buttons id attribute, because it should be unique.

Categories