express-handlebars # if statement - javascript

I am still pretty new to NodeJS and I am using the express and express-handlebar packages.
However, the 'if-statement' does not work properly, in fact not at all. I suppose the reason for this is that I do not use a template for the if-statement.
Using just the package 'handlebars', I would go with:
rs.readFile('files/test.hbs', 'utf-8', function(err, data)
{
var template = hbs.compile(data);
var result = template ({name: 'name', value1: 'value1', value2: 'value2'});
res.end (result);
...
}
This solution works actually.
However, I have already used express-handlebars in the entire code and would like to keep on using it. I got following code:
//I´ll receive value1 and value2 later either directly from my database or with the help of MQTT
var value1 = ' value1';
var value2 = 'value2';
var name = 'name';
var helpers={
value1:function(){return value1;},
value2:function(){return value2;},
name: function(){return name;}
}
router.get('/', function(req, res){
res.render('index', {helpers});
});
My html code looks like following:
<div>
<h1> {{value1}} </h1>
<h2> {{value2}} </h2>
{{#if name}}
<h3> hello there! </h3>
{{/if}}
</div>
value1 and value 2 are shown properly. 'hello there!' isn´t as I suppose it is not a template.
Does anyone know how I can make code work with express-handlebars?

I just answered it by myself.
The solution is:
router.get('/', function(req, res){
res.render('index', {
name,
helpers});
});

add this in server.js
const isEqual = function(a, b, opts) {
if (a == b) {
return opts.fn(this)
} else {
return opts.inverse(this)
}
}
var hbs = require('hbs');
hbs.registerHelper('if_eq', isEqual);

Related

How to reset json file in nodejs

I need to reset a json file to an original state after a button is clicked. Currently, I am modeling with router, and I need help to extend my existing code.
This is a code snippet I wrote on server.js file, the one that I run "nodemon" to start the server.
var messages = [{index:0, rating:0}, {index:1, rating:0}]
app.get('/votes', (req, res) =>{
res.send( messages )
})
app.post('/votes', (req, res) =>{
votes.push(votes)
res.sendStatus(200)
})
so my initial state on file 'votes' (json format) is:
[{"index":0,"rating":0}, {"index":1, "rating":0}]
After some user actions, I'll add some data to this json file using this code:
<body>
// some logic here
<script>
$(() => {
$("#submit").click(()=>{
var message = [ { index:1, rating: $("#input").val()},
{ index:2, rating: $("#input2").val()}]
postMessage(message)
})
})
function postMessage(message) {
$.post('http://localhost:8080/votes', message)
}
</script>
</body>
and then I have the following in my json file
[{"index":0,"rating":0}, {"index":1, "rating":0}, {"index":1, "rating":1}, {"index":2, "rating":3}]
QUESTION: How do I reset the json file (not json variable) into the initial state with a button click for a new transaction?
I am just doing prototyping, so a quick and dirty way may work.
I'd recommand build or use some sort of user verification, and for each user have a copy of the initial data just for him. Keep in mind that this data will never garbage collected so you will have to manage deletion by yourself. I used basic IP that is given by express but that is not a good practice.
Use npm-memorystore which will give your some memory management.
If you want to identify users you can use express-session, express-jwt
var messages = [{
index: 0,
rating: 0
}, {
index: 1,
rating: 0
}];
var usersMessages = {};
app.get('/votes', (req, res) => {
var userIp = req.ip;
usersMessages[userIp] = [].concat(messages);
res.send(usersMessages[userIp]);
});
app.post('/votes', (req, res) => {
var userIp = req.ip;
var userVotes = usersMessages[userIp];
if (!userVotes)
usersMessages[userIp] = [].concat(messages);
usersMessages[userIp].push(req.body.votes);
res.sendStatus(200)
});
Take a look this:
$(() => {
let message = [];
$("#submit").click(() => {
//fill with values
message = [
{ index: 1, rating: $("#input").val() },
{ index: 2, rating: $("#input2").val() }
];
postMessage(message); //send post
message = []; //reset array
});
function postMessage(message) {
$.post("http://localhost:8080/votes", message);
}
});
Hope this helps. =D
What you need to do is, just remove all of the object from array.
You can do that as follow.
var messages = [{"index":0,"rating":0}, {"index":1, "rating":0}, {"index":1, "rating":1}, {"index":2, "rating":3}];
messages.length = 1;
console.log(messages);
Another way.
var messages = [{"index":0,"rating":0}, {"index":1, "rating":0}, {"index":1, "rating":1}, {"index":2, "rating":3}];
messages = messages.slice(0,1);
console.log(messages);
What above code do is, it will just set array back to it first value.

How to access variable express from angularjs

first
exports.render = function(req,res){
res.render('index', {
title: 'welcome',
username : req.user ? req.user :''
});
};
I want to export object req.user to use
h2 Hello #{username.username}
h2 Hello #{username}
In Jade I can use it
div(ng-app='IndexController')
{{ #{username} | getUserData }}
but if i want to get it to angular it can't use
mainAppModule.filter('getUserData', function () {
return function (name) {
if (name)
console.log(name.username + "xxxxxxxxxxxxxxxxxxxxxxxxqqqqqqqqqq");
return 'Hellox, ';
};
});
How can i do it? how to get req.user for use in future.if there is other way to get object to use in angular please tell me.
Thank so much.
function MyCtrl($scope) {
$scope.req = {'user':'scope user'};
this.req1 = {'user':'alias user'} ;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
<div ng-controller="MyCtrl as myCont">
{{req.user}}
<br/>
{{myCont.req1.user}}
</div>
</div>
I am not sure what problem you are facing. You can simply use $scope or controller alias to access any variable in the view.
By Alias
<div ng-controller="MainController as main">
{{main.name.userName}}
</div>
By $scope
<div ng-controller="MainController">
{{name.userName}}
</div>
Seems you need to pass your request object to your Angular code.
What I can suggest is try to make a module which will act as a model for jade rendered objects as below:
index.jade
div(ng-controller="myController as ctrl")
h2 Title: {{ ctrl.title | myFilter }}
h2 Username: {{ ctrl.username | myFilter }}
script.
angular.module('jadeData',[])
.factory('jadeDataFactory',function(){
//model service to set objects retrieved from jade
return {
'title': "#{title}",
'username': "#{username}"
};
});
script(src="/js/app.module.js")
Once done, you can access the service model in you main module's controller
app.module.js
angular.module("myApp",['jadeData'])
.controller("myController",function(jadeDataFactory){
var that = this;
that.title = jadeDataFactory.title;
that.username = jadeDataFactory.username;
})
.filter("myFilter",function(){
return function(v){
if(v)
console.log('Inside filter value: ',v);
return v+' Modified';
}
});
This way you can inject the jadeDataFactory to any of the required controllers/services
Explanation: actually Jade is rendered in server side, and if you write {{ #{username} | getUserData }} then renderer could not get it correctly, the better way is to store it in a service model and access it in required controller.

Issue passing data to child routes in Node.js

Im new to Node.js and keep getting the Error: Route.get() requires callback functions but got a [object Undefined] error
and Ive checked out the following question and either dont understand or im still doing something wrong
Express routes: .get() requires callback functions but got a [object Object]
.get() requires callback functions but got a [object Undefined]
Error: Route.get() requires callback functions but got a [object Undefined]
Node Route.get() requires callback function but got a [object undefined]
my file structure is
server.js
routes/api/geolocations.js
routes/api/geolocations/regions.js
routes/api/geolocations/destination.js
ROOT: server.js
var geolocation = require('./routes/api/geolocation')(app);
app.get('/geolocation/', geolocation.delegate);
then I pass my data to routes/api/geolocations.js by using
geolocation.delegate(unparsedData);
from there I parse the data and send it down it's appropriate child routes.
PARENT: geolocations.js in my routes/api/geolocations.js
var destination = require('./geolocations/destination');
var region = require('./geolocations/region');
module.exports = function(app) {
return {
app.get('./geolocation/region', region.delegate);
app.get('./geolocation/destination', destination.delegate);
delegate: function(unparsedData, req, res) {
var data =[setup package for child states using unparsedData]
//HERE Id like to pass the new `data` to region or destination using the following
region.delegate(data);
//OR
destination.delegate(data);
CHILDREN: region.js / destination.js in routes/api/geolocations/regions.js or routes/api/geolocations/destination.js
module.exports = function(app) {
return {
delegate: function(data, req, res) {
...do stuff
}
}
}
UPDATE: I guess I dont know where to set up my routes, in server.js or if i can in geoloaction.js, does it matter, do need to do something like this in server.js?
var regions = require('./routes/api/geolocation/regions')([pass stuff here]);
geolocation.get('./routes/api/geolocation/regions', regions.delegate);
You should use express.js easy setup and run.
Simply download IntelliJ IDEA, find free version, then install. Then run the application and goto File->Setting->Plugin and search for NodeJS then install. Followed to this you need to Enable it. To do this goto File->Setting->Language & Frameworks->open arrow-> JavaScriptopen arrow->Libraries->Enable Node.js Core.
File Structure
routes/api/geolocations.js
routes/api/geolocations/regions.js
routes/api/geolocations/destination.js
You can have a look at the below code that might help you get started.
//------------------------------------------------------------------------
var express = require('express');
var router = express.Router();
var regions = require('../api/geolocations/regions');
var destination = require('../api/geolocations/destination');
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* geolocation.js */
router.get('/', function(req, res, next) {
var region_ext = regions.to_export;
var destin_ext = destination.to_export;
res.render('index', {
title: 'Geolocation',
region: region_ext,
destination:destin_ext
});
});
module.exports = router;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* region.js */
var to_export = function () {
return 'this is from regions';
}
module.exports.to_export = to_export();
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* destination.js */
var to_export = function () {
return 'this is from destination';
}
module.exports.to_export = to_export();
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//In app.js, just change
var routes = require('./routes/api/geolocations');
//------------------------------------------------------------------------
jfriend00 is right, You got a little mess there. Maybe you should consider make use of next(), since if you use it the other middlewares will have a chance of manipulating the request.

Sails.JS pass data from the view to the controller

in Sails.js, I am trying to pass the role/mentor key/value pair to be received by the contoller function '/select'
VIEW.ejs
...
$.post( '/select', {role: 'mentor'} );
...
CONTROLLER
select: function(req, res) {
var printRole = req.param('role');
return res.send("The role is: " + printRole);
}
So far the result I receive on the screen is : The role is Undefined
please help
I think param should be plural as in var printRole = req.params('role')

How to get a value from Jade to Javascript?

I know this looks repetitive, but it is a little bit different than the other question here.
I am using Node with the expressJS routing and passportJS login and in my login page I have a dropdown list to select a value that I want to pass along to my Angular script.
In my app.js I have:
var languages = [
{"lang": "English", "code": "en"},
{"lang": "Chinese", "code": "zh-cn"}
];
app.get('/', detectBrowser, routes.index);
app.get('/login', routes.login(isSameSubnet, languages));
index.js:
exports.index = function(req, res){
res.render('index', { login: 'Some String' });
};
exports.login = function(language) {
return function(req, res) {
res.render('login', { lang: language });
};
};
login.jade:
label.control-label Language
select.form-control
each val, index in lang
option(value= val.code)= val.lang
So how can I grab the value of the option tag back to my javascript and pass it to the next stage (AngularJS)?
I know how to get the information from the exports.index on the Angular side, but I don't know how to get the information I want and use it on this index function.
Thanks

Categories

Resources