Reputation: 829
I am stuck trying to query my database built using MongoDB (with Mongoose as the ODM) and displaying the results on the page. The database stores the data (comprising of date: 'date', and link: 'wwww.example.com') in a collection I named 'entries'. I have two views that I want to use to access the database: a view which will utilize the date key to display the right link on a particular day; and a view of the database where I can view, add and delete entries. I was somehow able to loop through the entries for the database view and add them to the DOM but when I try the same for the widget view I can't seem to access the JSON object from the entries collection. I'm using Jade as a preprocessor for my HTML
My app.js file is like so:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var router = express.Router();
//database stuff
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//connect to the data store and the set up the database
var db = mongoose.connection;
//connect to the database
var conn = mongoose.connect('mongodb://localhost/Mandela_Diaries/data');
//Create a model which connects to the schema and entries collection in the Mandela_Diaries database
var Entry = mongoose.model("Entry", new Schema({date: 'date', link: 'string'}), "entries");
mongoose.connection.on("open", function() {
console.log("mongodb is connected!");
});
var routes = require('./models/index');
var users = require('./routes/users');
var database = require('./routes/database');
var methodOverride = require('method-override');
var templatemain = require('./routes/template-main');
var app = express();
// Methodoverride at the top
app.use(methodOverride('_method'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
//serving static files
app.use('/public', express.static(__dirname + '/public'));
app.use('/public', express.static(__dirname + '/css'));
app.use('/public', express.static(__dirname + '/js'));
app.use('/public', express.static(__dirname + '/images'));
app.use('/public', express.static(__dirname + '/node_modules'));
app.use('/', routes);
app.use('/', routes);
app.use('/', routes);
app.use('/database', database);
app.use('/create', database);
app.use('/delete', database);
app.use('/:id', database);
// app.use('/database/#{entry._id}?/delete', database);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
module.exports.Entry = Entry;
app.listen(8080);
console.log("The server has started");
My database.js router code is like so:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Entry = mongoose.model('Entry');
//The route for getting data for the database - GET form
router.get("/", function(req, res) {
//Send the current entries to the page
Entry.find({}, function(err, entries) {
console.log(entries);
if(err) {
res.status(404).json({"error": "not found", "err":err});
return;
} else {
res.render('database', {title: 'database', entries: entries});
//console.log(entries);
//entries.forEach(printjson);
}
});
});
//The route for posting data to the database - POST
router.post('/', function(req, res) {
var newEntry = new Entry(req.body);
newEntry.save(function(err, entries){
if (err !== null) {
res.status(500).json(err);
} else {
res.redirect('database');
};
});
});
//The route for deleting data to the database - Delete/remove todo item by its id
// Changed path from `/` to `/:id`
router.delete('/:id', function (req, res) {
Entry.findById(req.params.id)
.exec(function(err, entries) {
// changed `if (err || !doc)` to `if (err || !entries)`
if (err || !entries) {
res.statusCode = 404;
res.send({});
} else {
entries.remove(function(err) {
if (err) {
res.statusCode = 403;
res.send(err);
} else {
res.send('Deleted entry with link: ', entries.link);
}
});
}
});
});
module.exports = router;
My index.js router code is like so:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Entry = mongoose.model('Entry');
var moment = require('moment');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('/', { title: 'Express' });
Entry.find({}, function(err, entries) {
if(err) {
res.status(404).json({"error": "not found", "err":err});
return;
} else {
res.render('/', {title: 'database', entries: entries});
}
});
});
console.log("new code works");
module.exports = router;
My script.js code running the jQuery to append the correct video links according to the date is like so:
$(document).ready(function() {
//Date picker jQuery
$(function() {
$( ".datepicker" ).datepicker();
$( "#format" ).change(function() {
$( ".datepicker" ).datepicker( "option", "dateFormat", $( this ).val() );
});
});
var browserDate = new Date();
var videoDate = new Date(1962);
//var month = browserDate.getMonth() + 1;
//var day = browserDate.getDate();
//var year = browserDate.getFullYear();
var context = browserDate - videoDate;
$('#context').innerHTML = "ON THIS DAY " + context + " YEARS AGO:";
console.log("ON THIS DAY " + context + " YEARS AGO:");
console.log("This worked!!");
console.log(browserDate);
});
And my Jade code for index.jade is like this:
extends layout
block content
#widget.container
.row
#header.col-xs-12.header
img#Mandela_Logo(src='/public/images/Logo_MandelaDiaries.png')
.row
#context.col-xs-12
.row
#videos.col-xs-12
.embed-responsive.embed-responsive-4by3
iframe(width='300', height='169', src='https://www.youtube.com/embed/4HqtAMHrJ8s', frameborder='0', allowfullscreen='')
.row
#footer.col-xs-12
img#NMF_logo(src='/public/images/Logo_NMF.png')
img#SABC_logo(src='/public/images/Logo_SABCNews.png')
I can't seem to be able to get my jQuery to work here. I just want to get the JSON object and loop through it and find the relevant day, based on the browser date, and attach the corresponding link to the iframe in my widget.
Upvotes: 1
Views: 114
Reputation: 103365
To simplify things, you could use the momentjs library which is great at dealing with dates. In your use case, you want to use the fromNow()
method which displays the relative time from now, say for example
moment([2011, 0, 29]).fromNow(); // 4 years ago
moment("1962-04-08T09:48:16.189Z").fromNow() // 53 years ago
To use the momentjs library in your views, you need to add it to your express application locals as follows:
express = require('express');
...
var app = express();
app.locals.moment = require('moment');
Since you can use plain JavaScript code in in your Jade views, you can easily do:
extends layout
block content
#widget.container
.row
#header.col-xs-12.header
img#Mandela_Logo(src='/public/images/Logo_MandelaDiaries.png')
.row
#context.col-xs-12
each entry in entries
p= 'ON THIS DAY ' + moment(entry.date).fromNow() + ' - Link: ' + entry.link + ' '
.row
#videos.col-xs-12
.embed-responsive.embed-responsive-4by3
iframe(width='300', height='169', src='https://www.youtube.com/embed/4HqtAMHrJ8s', frameborder='0', allowfullscreen='')
.row
#footer.col-xs-12
img#NMF_logo(src='/public/images/Logo_NMF.png')
img#SABC_logo(src='/public/images/Logo_SABCNews.png')
Source: Making use of utility libraries in server-side Jade templates
Upvotes: 1