mongoose syntax with user.id connecting to a form - javascript

Hi I am new to mongoose and with angular through ionic. I am trying to build an app and having problem with it. I have no Idea if this syntax mongoose is right because it still is not working in my front end where the user picks and answer and it saves it to the database
Heres my mongoose question.js
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Question = require('../models/Question.js');
var app = express();
// GET questions listing. questions/yourroute
router.get('/', function(req, res, next) {
Question.find(function(err, questions){
if(err) return next(err);
res.json(questions);
});
});
router.post('/saved-questions', function(req, res){
var now = Date()
User.findById(user.id, function(err, user){
var newanswer1 = {
question: '58ccb991caf9756f8e1d8a6c',
answer_text: req.body.Q1,
postdate: now
}
});
user.users_answers.push(newanswer1);
//repeat for Q 2 and 3, push each time
User.save()
});
module.exports = router;
And this is the form in ionic.. I don't know why its not working, maybe its how im putting it in the ionic form. There suppose to be slides of questions in ionic and each possible answer is in the ion check box
<div id="questions" ng-controller="QCntrl">
<ion-content>
<ion-slide-box>
<ion-slide>
<div class="intro" ng-controller="PopupCtrl">
<h1 class="hidden">Intro Question</h1>
<h3>Just need to ask some questions to make this app personalized for you</h3>
<button class="button" value="next" ng-click="nextSlide()">OKAY</button>
<button class="button2 button-positive" ng-click="PopAlert()">
Why?
</button>
</div>
</ion-slide>
<ion-slide>
<div id="Q1box">
<h2>{{questions[0].question_text}}</h2>
<ul>
<li data-ng-repeat="answer in answers1">
<ion-checkbox id="Q1" ng-model="filter.users_answers">{{answer.label}}</ion- checkbox>
</li>
</ul>
Next Question
</div>
</ion-slide>

Where you have User.save(), try changing it to user.save and move the }) that's before User.save and put it after where you change User.save to user.save
You are editing the user you just found with User.findById(user.id, function(err, user){
and it seems you then want to save the push you made to user.users_answers which user.save should do for you

Related

Express js/Handlebars newbie - Using res.locals.currentPost only works in some cases and cannot figure out why

This is my first time posting on stack overflow, ill try my best to describe my issue.
I am working on a image website project (think imgur/flickr) and am using handlebars templating for the first time. I've made a page to view individual photos with the photo info (who posted it and description) and a comments section. The comments section works perfectly but the photo and photo info wont load.
I have been trying for hours and I cannot figure out why its only working for one and not the other. I wrote error codes to follow the info and it does make it to the middleware needed for the page but doesn't appear on the page.
Here is my code for the middleware page:
var {getMRecentPosts, getMPostById} = require('../models/Posts');
const {getCommentsForPost} = require('../models/Comments');
const { errorPrint, successPrint } = require('../helpers/debug/debugprinters');
const postMW = {};
postMW.getPostById = async function (req, res, next) {
try{
successPrint(req.params.id);
let results = await getMPostById(req.params.id);
successPrint(results[0]);
if(results && results.length){
res.locals.currentPost = results[0];
errorPrint(res.locals.currentPost);
next();
}else{
req.flash("error", "This is not the post you are looking for.");
res.redirect('/');
}
}catch(error){
next(error);
}
}
postMW.getCommentsByPostId = async function (req, res, next) {
try{
let results = await getCommentsForPost(req.params.id);
res.locals.currentPost.comments = results;
next();
}catch (error){
next(error);
}
}
module.exports = postMW;
Here is the console message from my errorPrinter (again there's no actual system error just trying to make sure the info is making it this far):
[
BinaryRow {
username: 'dan',
title: 'Flying fox back at it again',
description: 'Once a gain not actually a fox, just called on',
photopath: 'public\\images\\uploads\\3404ba6eb264c819ff7011378b756c8426c17e4d57bc.jpeg',
created: 2020-12-20T00:28:28.000Z
}
]
Here is my code for the Hbs file:
<div id="post-container">
<div id="photo-container">
<div id="post-title" class="display-6 font-weight-bold">{{currentPost.title}}</div>
<div id="post-info">
<p><span class="form-label">Posted by:</span>
<span id="post-author">
{{currentPost.username}}
</p>
<p><span class="form-label">Posted at:</span><span id="post-date">{{currentPost.created}}</p>
</div>
<div id="post-description" class="lead">{{currentPost.description}}</div>
<img id="post-image" class="img-fluid" src="/{{currentPost.photopath}}" alt="A photo should have been here">
</div>
<div id="comment-container">
<div id="messages">
{{#each currentPost.comments}}
{{> comment this}}
{{/each}}
</div>
<div id="comment-box">
<textarea id="comment-box-text" class="form-control" aria-label="With textarea"
placeholder="Enter Comment Here!"></textarea>
<span id="comment-box-button" class="input-group-text"><img src="https://img.icons8.com/metro/26/ffffff/paper-plane.png"/></span>
</div>
</div>
</div>
Any insight is welcome!!! I'm so blind to what the error is and/or I'm just really bad at googling for correct help lol

button should delete specific item on server side

I'm working on an app to track my expenses with javascript, nodejs , express and as templating engine handelbars.
So I have a div "list" which contains all expenses. ( i have an add button next to the div list, not visible on the pic)
Everytime a I add an expense , I add the div "obj" with a delete button ,a "B" button and some information about the expense.
here is the code in my html:
<div class="list">
{{#each expArr}}
<div id="obj" class="obj">
<form action="/removetodo" method="POST" >
<button class="btn2">X</button>
</form>
<button onclick="openNav()" class="btn">B</button>
<a>{{date}}</a> <n>{{name}}</n> <a>{{value}} </a>
{{description}}
</div>
{{/each}}
Now, my backend is runnning on a NodeJS server with express.
here is my index.js file :
var express = require('express');
var router = express.Router();
var expArr = [];
router.get('/', function(req, res, next) {
res.render('index' , {expArr: expArr} );
});
router.post('/addtodo', function (req, res, next) {
var exp = new Object();
exp.name = req.body.name;
exp.value = req.body.val;
exp.date = req.body.date;
exp.description = req.body.descr;
expArr.push(exp);
res.redirect('/');
});
router.post('/removetodo', function (req, res, next) {
expArr.pop();
res.redirect("/");
});
module.exports = router;
In addtodo I simply adding all the informtion to an array on the server (later I will add a database).
Now my question:
The delete button on every expense should delete the right expense.
In other words, I want ,by clicking the delete button , that the right entry in the array on the server deletes.
How do I do that?
Thanks!
you're storing everything in memory, taking that for granted, you can start by using a plain object rather then an array to store your data
expArr = {}
and then add a unique identifier like a hash or a date in ms for each instance
var exp = new Object();
exp.id = new Date().getUTCMilliseconds();
exp.name = req.body.name;
exp.value = req.body.val;
exp.date = req.body.date;
exp.description = req.body.descr;
expArr[exp.id] = exp;
now be sure to pass from the client the right id when you want to remove an expense
router.post('/removetodo', function (req, res, next) {
if(expArr[req.body.id]) {
delete expArr[req.body.id];
}
res.redirect("/");
});

ReCaptcha validation on Node.js

on my express server, g-recaptcha-response always return nothing. This is my code at the moment:
<div class=container-fluid id=mcenter>
<form id='monitstart' action="/monitstart" method="POST">
<input type="text" class="form-control" aria-label="..." name=>
<button class="g-recaptcha" data-sitekey="SITEKEYHERE" data-callback="onSubmit"></button>
</form>
</div>
and on my server
var express = require('express')
var router = express.Router()
var request = require('request')
router.post('/monitstart', function (req, res) {
request({url: "https://www.google.com/recaptcha/api/siteverify?secret=SECRETHERE&response=" + req.body['g-recaptcha-response']} + '&remoteip=' + req.connection.remoteAddress, function (err, response, body) {
req.send(body)
})
})
module.exports = router
And when I try to validate it, it give me a code 500 and say TypeError: Cannot read property 'g-recaptcha-response' of undefined
The correct answer, accepted by the OP during the short discussion below the question involves adding the body parsing middleware (the body-parser) to the pipeline so that the body property of the request object is correctly initialized before a value is read from there.

angular and socket io class manipulation

I am bulding a chat app with angular on the front end and socket io for the chat platform.
I want to have a diffenet css class for the sender in the chat (the one who sends the message in the chat) and for the side that recieves the message.
to do that I've created 2 classes in my css: "sender" and "reciever".
I want that when my socket gets a message from the "sender" (aka "the speaker side") - the li class will be "sender". when the socket gets a message from outside (some other member in the chat the is not me) the class will be "reciever".
like the green and white here: http://www.androidpolice.com/wp-content/uploads/2015/07/nexus2cee_whatsapp-middle-finger-2.png
I know that I can change the class in angluar using the ng-class directive.
The problem is that when I do the class manipulate all the messages in my chat became a part of that class (I am using ng-repeat directive).
and what I want is that 1 message will be class A and other message will be from class B and 3rd message will be class A.... so on...
I know that I should somehow use the ng-class propertie like:
<li ng-class={'sender' : message.sender, 'btn-off' : !message.sender} ng-repeat="message in messages track by $index">{{message}}</li>
but how can I get the message object (which is a string to include a boolean as well?
can you please help me to figure out how I can write the code for that?
this is my controler
mymodule.controller("cntrlChat", ['$scope', 'myService','$q','$timeout',
function($scope, myService,$q,$timeout){
var socket = io();
$scope.messages = [];
$scope.message_type="sender";
$scope.room= myService.get().room;
$scope.name= myService.get().name;
socket.emit('room', $scope.room);
$scope.submit=function(){
socket.emit('chat_message',{ room: $scope.room, msg: $scope.name+": "+$scope.insertedText });
$scope.message_type="sender";
$scope.messages.push($scope.name+": "+$scope.insertedText);
$scope.insertedText='';
return false;
}
socket.on('chat_message', function(msg){
$scope.$apply(function() {
$scope.message_type="receiver";
$scope.messages.push(msg);
});
});
socket.on('info_message', function(msg){
$scope.$apply(function() {
$scope.info=msg;
});
});
this is the server.js file:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
app.use(express.static(path.join(__dirname, '/')));
app.get('/', function(req, res){
res.sendFile(__dirname + '/Index.html');
});
io.on('connection', function(socket){
io.emit('chat_message', "welcome");
socket.on('room', function(room) {
socket.join(room);
});
socket.on('chat_message', function(data){
socket.broadcast.to(data.room).emit('chat_message',data.msg);
});
socket.on('info_message', function(data){
socket.broadcast.to(data.room).emit('info_message',data.msg);
});
socket.on('disconnect', function(){
io.emit('chat message', "Bye");
});
});
http.listen((process.env.PORT || 3000), function(){
console.log('listening on *:3000 '+ __dirname);
});
this is the html for my chat:
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="chat">
<div class="members">
{{users}}
</div>
<div class="messages">
<ul>
<li ng-class="message_type" ng-repeat="message in messages track by $index">{{message}}</li>
</ul>
</div>
<form ng-submit="submit()">
{{info}}
<br>
<input autocomplete="off" ng-model="insertedText" ng-change="isUserTyping()" type="text" />
<button type="button" ng-click="submit()">
Send
</button>
</form>
</div>
</body>
Ok let's take a crack at this.
On a high level description, we want the socket to pass messages between users.
The best way to ensure we know who sent what is to make sure the data we pass has the right details.
With that being said, you just need to turn the msg from a string to an object and pass that around with a flag (I used sender/receiver, you can use sender: true/false):
$scope.submit=function(){
//
// change msg to an object (I don't know io well so it may need to be json encoded decoded?)
//
socket.emit('chat_message', {
room: $scope.room,
msg: {
text: $scope.name+": "+$scope.insertedText,
status: 'sender'
}
});
//
// push the data obj to your messages array
//
$scope.messages.push(msg)
$scope.insertedText='';
return false;
}
socket.on('chat_message', function(data){
$scope.$apply(function() {
//
// we expect data to look like the data above except we'll change the flag when it's retrieved
//
data.status = 'received'
$scope.messages.push(data);
});
});
socket.on('info_message', function(msg){
$scope.$apply(function() {
$scope.info=msg;
});
});
We're now passing objects with flags to and from the node server without modification on the server side so that code doesn't need to change at all.
Finally, the angular part:
<div class="chat">
<div class="members">
{{users}}
</div>
<div class="messages">
<ul>
//
// ng class stuff
// (ternary) ng-class="message.status === 'received' ? 'class1' : 'class2'"
//
<li ng-class="{'class1': message.status === 'sender', 'class2': message.status === 'received'}" ng-repeat="message in messages track by $index">{{message.text}}</li>
</ul>
</div>
<form ng-submit="submit()">
{{info}}
<br>
<input autocomplete="off" ng-model="insertedText" ng-change="isUserTyping()" type="text" />
<button type="button" ng-click="submit()">
Send
</button>
</form>
</div>

node.js + express.js & hogan.js: returns a blank page sometimes

Everything in this app works fine but sometimes i get a blank page rendered instead of the homepage (or any other page for that matter). Then when i change something small in the affected view (like for instance add a space, or .) the page renders normal again.
I think that the problem may be a async issue but i can't locate it.
I'm using:
node.js
express.js
consolidate
hogan.js
UPDATE 1:
This seems to happen only in the safari browser, very strange, maybe it's a css thing, i'll investigate.
UPDATE 2:
It's definitely not a CSS thing.
The main express app setup:
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
dependencies
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
var express = require("express")
var cons = require("consolidate")
var app = express()
var path = require("path")
var index = require("./routes/index")
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
configure
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
app.configure(function(){
app.engine("html", cons.hogan)
app.set("view engine", "html")
app.set("views", __dirname + "/views")
app.use(express.static(path.join(__dirname, "public")))
})
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
routes
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
app.get("/", index.index)
app.get("/hire", index.hire)
app.get("/hire/:id/:nr", index.hirePerson)
app.get("/books", index.books)
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
listen
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
app.listen(2020)
Then in my index.js route file:
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
settings
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
var appURL = new function(){
this.home = "/",
this.hire = this.home + "hire"
this.books = this.home + "books"
this.projects = this.home + "projects"
this.portfolio = this.home + "portfolio"
}
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
routes
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
exports.index = function(req, res){
res.render("index.html", {url:appURL, partials:{footer:"footer", header:"header"}})
}
exports.hire = function(req, res){
res.render("hire.html", {url:appURL, partials:{footer:"footer", header:"header"}})
}
exports.books = function(req, res){
res.render("books.html", {url:appURL, partials:{footer:"footer", header:"header"}})
}
exports.hirePerson = function(req, res){
res.render("hireDetail.html", {id:req.params.id, nr:req.params.nr})
}
One of my views (index.html)
{{> header}}
<section class="layoutIndex"><div class="layoutIndex-container">
<header class="layoutIndex-header">
<nav class="navHeader">
<h1 class="navHeader-logo"><a class="bf-logo" href="{{url.home}}"></a><span>Basing.com</span></h1>
<h2 class="navHeader-slogan">HTML / CSS / JS werkgroep</h2>
<ul class="navHeader-buttons modelTernary">
<li class="modelTernary-column"><a class="buttonPrimary" href="{{url.hire}}">Hire us</a></li>
<li class="modelTernary-column"><a class="buttonPrimary" href="{{url.books}}">Books</a></li>
<li class="modelTernary-column"><a class="buttonPrimary" href="{{url.projects}}">Projects</a></li>
</ul>
</nav>
</header>
<section class="layoutIndex-articles">
<article class="books">
<h2>Books <time>2014</time></h2>
<ul class="listArticles">
<li><h3>Javascript variables, what's so special about them?</h3></li>
<li><h3>Javascript variables, what's so special about them?</h3></li>
</ul>
</article>
<div class="hrLight"></div>
<article class="projects">
<h2>Projects</h2>
<h3 class="icon"><i class="bf-logo"></i>CSS Objects: a front-end methodology</h3>
</article>
</section>
</div></section>
{{> footer}}
I'm pretty sure we're seeing the 304 bug here.
More here: http://tech.vg.no/2013/10/02/ios7-bug-shows-white-page-when-getting-304-not-modified-from-server/
Basically, when you server returns a "304 - Not modified" response. Safari breaks it.
The way to fix this is to disable "etag" responses (you could target only ios requests) by disabling the 'etag'.
app.disable('etag');
Express recently integrated this here: https://github.com/visionmedia/express/commit/610e172fcf9306bd5812bb2bae8904c23e0e8043
So in your case (disabling etag globally):
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////
configure
///////////////////////////////////////////////////////////////////////////////////////////////////////////*/
app.configure(function(){
app.engine("html", cons.hogan)
app.set("view engine", "html")
app.set("views", __dirname + "/views")
app.use(express.static(path.join(__dirname, "public")))
app.disable('etag');
});
Fair warning: I am still getting 304 headers with this, but safari doesn't seem to show the blank white page unless I double tap the reload button. Either way, if I single tap, the page seems to load reliably.

Categories