My controllers looks like this in usermains.js
var header = function (req, res, next) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.locals.title="helloooo";
res.write(loadView('headerpage'));
console.log(res.title);
next();
};
app.get('/log',header,values,renderBody);
Here is my loadview function
var loadView = function(name, locals) {
if(name=='main'){
console.log(path.join('views/layouts/'+name + '.hbs'));
var template = fs.readFileSync(path.join('views/layouts/'+name +'.hbs')).toString();
}else{
console.log(path.join('views/'+name + '.hbs'));
var template = fs.readFileSync(path.join('views/'+name + '.hbs')).toString();
}
return template;
};
And i am calling this on view page.
{{title}}
It is giving output as {{title}} on browser. How to get res.locals.title value on view page. Thanks!
Use Handlebars in order to first compile, and then execute the template, passing the appropriate data that you wish. Simply reading/loading the template will give you the raw data. Use something like (tweak it for your needs, this is only a sample):
var handlebars = require('handlebars');
var rawTemplate = fs.readFileSync(path.join('views/'+name + '.hbs')).toString();
var compiledTemplate = handlebars.compile(rawTemplate);
var result = compiledTemplate(dataPassedToTemplate);
res.write(result);
Related
test.ejs
<form action="/test2" method="post"><input type="text" /><input type="submit" /></form>
test.js
var express = require('express');
var app = express();
var router = express.Router();
router.post('/test2', function(req, res) {
res.render('test2'); // cause we need to render the page we send socket.io data to
var socket_data = 'sd';
req.io.in(room).emit('socket',{
socket : socket_data
}); // socket data is send
var body = req.body.form_input; // our input value
var someMoreCodeForExample = request('https:/www.google.com', function(err, resp, google){
if (resp){
res.render('test'); // can't render twice cause of first render is in the game... <-
}
}
if (body == 'wrong'){
var input_error = 'error';
res.render('test', {errors : input_error}); // if input is wrong we redirect user to form page so he can use it again - can't render twice cause of first render is in the game... <-
}
}
So if user insert wrong input - he is redirected back to 'test' to submit correct input data. But... 'Can't set headers after they are sent.' how I can avoid this in this particular case (it's cause of 2x res.render but then how can I redirect user back to form?)?
You need to change you're route to first test for req.body and then render based on its value:
router.post('/test2', function(req, res) {
var body = req.body.form_input; // our input value
if (body === 'wrong') {
var input_error = 'error';
res.render('test', {errors : input_error});
} else {
res.render('test2');
}
})
The reason for your error is you're first rendering test2 (i.e, sending a response) then testing for req.body value.
When I create a JsonClient in node I do the following:
var client = restify.createJsonClient({
url: 'https://www.domain.com:4321/api'
});
Once I've done that, I make calls like so:
client.post('/service/path', { });
Which seems right. I expect that the path called would be something like https://www.domain.com:4321/api/service/path. However, what is happening is that the client is throwing away the /api base path and calling https://www.domain.com:4321/service/path.
I don't get it - I'm inserting the client URL into a config file, so that I can change hosts without any hassle; Now that I need a base path, I need to change the code as well as the config.
If you put a wrapper around the restify JsonClient stuff you could do it with minimal code change and the config would, I think, work the way you want it.
Create a library file myClient.js
'use strict';
var restify = require('restify');
var jsonClient = null;
module.exports = {
createJsonClient: function(opts){
var opts = opts || {};
var url = opts.url;
var parts = url.split('/');
var main_url = parts[0] + '//' + parts[2];
var basePath = parts[3] ? parts[3] : '';
jsonClient = restify.createJsonClient({url: main_url});
return {
get: function(path, cb){
var adjusted_path = '/' + basePath + path;
jsonClient.get(adjusted_path, function(err2, req2, res2, obj2){
return cb(err2, req2, res2, obj2);
});
}
}
}
}
Then use it like this.
var myClientWrapper = require('./lib/myClient');
var client = myClientWrapper.createJsonClient({url: 'http://localhost:8000/api'});
client.get('/service/path/one', function(err, req, res, obj){
if(err){
console.log(err.message);
return;
}
console.log(res.body);
});
It could use some more error checking and the url parsing is a little brittle, but it does work. I tried it out. Of course, I only wrapped the get function but you can see how it would work for the others.
I'm trying to get some html from a page online and place inside my jade template so I can style without copying and pasting every time a need it.
var request = require("request");
var cheerio = require("cheerio");
var loadContent = function() {
request({
uri: "http://www.mywebsite.com.br/test"
}, function(error, response, body) {
var $ = cheerio.load(body);
var result;
$('.content').each(function(){
result={"content":$(this).html()};
});
placeContent(result);
return true;
});
};
var placeContent = function(content) {
return content;
};
module.exports = loadContent;
Inside my gulpfile.js, besides the right requirements, I have:
gulp.task('jadeBuild', function() {
var options = {
pretty: true
};
return gulp.src(src+'/*.jade')
.pipe(data(function(){
return loadContent();
}))
.pipe(jade(options))
.pipe(gulp.dest(build))
.pipe(connect.reload());
});
And my jade file:
.mycontent
#{content}
What am I missing?
Try changing #{content} to !{content} in your jade file. This will tell jade not to escape any of the characters(which can be dangerous depending on where the input is coming from!).
See http://jade-lang.com/reference/interpolation/
Also, when you loop over each .content you are overwriting result every time. You need to append to result if you want to aggregate all the content together. Something like:
var result = {content: ''};
$('.content').each(function(){
result.content += $(this).html();
});
I have a text area, where the user type in their text. Once they click save the content in the text area is send to the server side. In the server side I want to use the content to create a file. I have a variable called "usercode" which holds the content of the text area. I create a file,
fs.wirteFile(name + "java", usercode, function(){})
Name the file name, given by user. This does create a file, however the only thing in the file is "[object Object]".
here is my client side I am using jade:
extends layout
block content
div(id="ineditortxt")
h1(name="headings") #{title}
a(href='/signout', class='text-center new-account') Sign Out
div(id="editor")
|public class #{title}{
| public static void main(String[] args) {
|
| }
|}
script(src="src/ace.js", type="text/javascript")
script(type="text/javascript").
//var myRequest = new XMLHttpRequest();
var editor=ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/java");
$(document).ready(function(){
$("#save").click(function(event){
var content = editor.getValue();
$.ajax({
url:'/getcode',
type:'POST',
data: content,
jsonpCallback: 'callback'
});
event.preventDefault();
return false;
});
});
form(name="Save", id = "save")
input(type="submit", value="Save")
div(id="result")
|
Here is the server side i didn't include all the code, just the one related to this question:
var express = require('express');
var router = express();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var param = require('express-params');
var Parse = require('parse').Parse;
var http = require('http');
var fs = require('fs');
router.post('/editor', function(req, res){
name = req.body.newname;
res.render('Editor', {title: "" + name});
});
router.post('/getcode', function(req, res){
var usercode = req.body;
fs.writeFile(name + ".java", usercode, function(err){
if(err){
console.log(err);
} else{
console.log("The file is saved!");
}
})
res.send({code: "" + usercode});
console.log(usercode);
});
return router;
}
You are actually writing the req.body object to the file which is a JSON object to access the post data in your request.
You need to access the post data by form field name inside that object so if you have a form field named "myField", it's data will be available in req.body.myField
If you want to just write the whole object to the file, you need to first stringify the JSON object using JSON.stringify(req.body)
JSON.stringify is going to escape the string which you can fix by unescaping it using unescape(string)
On client side the code should be:
$(document).ready(function(){
$("#save").click(function(event){
var content = editor.getValue();
console.log("This is content: " + content);
$.ajax({
url:'/getcode',
type:'POST',
data: {'code': content},
processData: 'false',
});
event.preventDefault();
return false;
});
});
on the server side the code should be:
router.post('/getcode', function(req, res){
var usercode = req.body.code;
newname = name+".java";
I want to make my express route have the ability be able to pass anything past the first set of parameters to it
app.get('/views/app/:name/*', appRoutes.partials);
and in my route file I have
exports.partials = function(req, res) {
var name = req.params.name;
var partial = req.params.partial;
var content = "";
res.render('views/app/'+name+'/'+partial,content);
};
I know partial would not be the variable to use there but how can I make whatever passes through the star append to the end?
I hope this makes sense.
The star (*) placeholder will capture all the remaining text and place it under key '0' on params object (if you had more *'s, they would go to '1', '2'...).
So, how about this:
exports.partials = function(req, res) {
var name = req.params.name;
var partial = req.params['0'];
var content = "";
res.render('views/app/'+name+'/'+partial,content);
};
If you expect the wildcard part to be an arbitrary route, you will have to parse it yourself. For example:
// url: /views/app/profile/main/dashboard
exports.partials = function(req, res) {
var path = req.params['0'].split('/');
console.log(path[0], path[1]); //>> main dashboard
};