using data from script file in handlebars template - handlebars.js

I'm working on node.js/express app and I'm using handlebars as a template engine. I know how to send data to hbs template using res.render('results',{data}) but in this case this is not possible. I'm trying to display some data generated in script.js on handlebar template page but I can't make it.
I have tried to include
<script id="selected-analysis" type="text/x-handlebars-template">
{{#if visibility}}
{{city}}
{{/if}}
</script>
<div class="content-placeholder"></div>
on results.hbs page and code bellow on script.js page
let theTemplateScript = document.getElementById("selected-analysis").innerHTML;
let theTemplate = Handlebars.compile(theTemplateScript);
let display = {
"visibility":true,
"city":'beo'
}
let theCompiledHtml = theTemplate(display)
document.querySelector('.content-placeholder').innerHTML += theCompiledHtml
On main.hbs I have
<script src="/dist/handlebars-v4.4.3.js"charset="utf-8"></script>
In my app.js file I have set handlebars middleware
app.engine('.hbs', exphbs({
defaultLayout:'main',
helpers:helpers,
extname:'.hbs'
}))
app.set('view engine', 'hbs')
could anyone tell me what I'm doing wrong.
thanks

Please try using app.set('view engine', '.hbs'); in app.js.
Please modify app.js as below
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
app.engine('.hbs', exphbs({
defaultLayout:'main',
helpers:helpers,
extname:'.hbs'}));
app.set('view engine', '.hbs');

Related

Style sheet is not getting linked while using EJS

I am learning to use ejs, express, node js. I am having probling my style sheet to my header here is my code and here is a . I am using header and footer as include. Here is my
My app.js-
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const app = express();
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
app.get("/", function(req, res) {
res.render("home");
});
app.listen(3000, function() {
console.log("Server started on port 3000");
});
2 things to note here
style.css is an external css file. So you dont need style tags inside that file. It should only contain the css.
In your express app, you have to mention the public directory from which you are serving the static files. Like css/js/image
it can be done by
app.use(express.static(__dirname + '/public'));
assuming you put the css files in public folder from in your app root. now you have to refer to the css files in your tamplate files, like
<link href="/css/style.css" rel="stylesheet" type="text/css">
Here i assume you have put the css file in css folder inside your public folder.
So folder structure would be
.
./app.js
./public
/css
/style.css
close head tag appropriately

css file is not served in my nodejs application

Hello guys I dont understand why my css file is not served when the url contains parameters. I want to access a route from another route when I click on the link here : click here located in welcome file.Below is my server config : app.js
let express = require("express");
let path = require("path");
let mongoose = require("mongoose");
let bodyParser = require('body-parser');
let exphbs = require('express-handlebars');
let dotenv = require("dotenv").config();
let app = express();
app.use(express.static(path.join(__dirname,"public")))
app.set("views","views");
app.set("view engine","hbs");
app.engine("hbs",exphbs({
extname:"hbs",
layoutsDir:path.join(__dirname,"views"),
defaultLayout:"template",
partialsDir:path.join(__dirname,"views/partials/")
})) ;
######ROUTING
app.get("/",(req,res)=>{
res.render("welcome") // from which I access "/books/:id" route : css file is served
})
app.get("/books/:id",(req,res)=>{
let p_id = req.params.id;
//here css file is not served but if I access without parameter,css file is served so WHY??????
res.render("bookdetail")
})
NB : my css file is called home.css
My template file template.hbs
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="home.css">
<title>ziri book</title>
</head>
<body>
{{{body}}}
</body>
</html>

please how can l add a runtime option to disable the check or this warning

I am creating a contact form that will display some messages on screen for the user to know that form was submitted successful
but,l am always receiving error message in my git terminal. Below is the error message.
Handlebars: Access has been denied to resolve the property "message" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Below is server.js and message.handlebars code;
app.post('/contactUs',function(req,res){
console.log(req.body);
//res.send('thanks');
const newMessage = {
fullname: req.body.fullname,
email: req.body.email,
message: req.body.message,
date: new Date()
}
new Message(newMessage).save(function(err, message){
if (err){
throw err;
}else{
Message.find({}).then(function(messages){
if(messages){
res.render('newmessage',{
title: 'Sent',
messages:messages
});
}else{
res.render('noMessage',{
title: 'Not found'
});
}
});
}
});
});
<h1>Thank you for contacting</h1>
{{#each messages}}
<p>{{fullname}}</p>
<p>{{email}}</p>
<p>{{message}}</p>
<small>{{date}}</small>
<hr>
{{else}}
<p>No messages</p>
{{/each}}
<button class="btn btn-success">Contact Again</button>
I'm guessing your doing the same dating app tutorial I am working on. I solved this problem by following the given link: https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access
Then I downloaded the package npm install #handlebars/allow-prototype-access
Then in server.js add:
const express = require('express');
const Handlebars = require('handlebars')
const expressHandlebars = require('express-handlebars');
const {allowInsecurePrototypeAccess} = require('#handlebars/allow-prototype-access')
Scroll down in server.js to app.engine:
// setup view engine
app.engine('handlebars', exphbs({
defaultLayout: 'main',
}));
app.set('view engine', 'handlebars');
Then add: handlebars: allowInsecurePrototypeAccess(Handlebars)
It should look like this:
// setup view engine
app.engine('handlebars', exphbs({
defaultLayout: 'main',
handlebars: allowInsecurePrototypeAccess(Handlebars)
}));
app.set('view engine', 'handlebars');
I hope this helps. Good Luck.
you can add .lean() to your model for example await Basic.findById(result.id).lean()
This may be happening because of the latest version of Handlebars, but this can be solved by adding a dependency to handlebars.
npm i -D handlebars#4.5.0
Just use the exact same version of "express-handlebars" , which was shown in the tutorial. The latest version of handlebars is causing the problem.
Atleast doing this , worked for me.
This worked for me, pretty similar to the first answer:
const express = require('express');
const handlebars = require('handlebars')
const expressHandlebars = require('express-handlebars');
const { allowInsecurePrototypeAccess } = require('#handlebars/allow-prototype-access')
// configuration express for handlebars
app.engine('hbs', expressHandlebars({ extname: 'hbs',
defaultLayout: 'mainLayout',
handlebars: allowInsecurePrototypeAccess(handlebars),
layoutsDir: __dirname + '/views/layouts/' })
);
const Handlebars=require('handlebars')
const {allowInsecurePrototypeAccess} = require('#handlebars/allow-prototype-access')
app.engine('handlebars',exphbs({defaultLayout:'main',
handlebars: allowInsecurePrototypeAccess(Handlebars)
}));
app.set('view engine','handlebars');
this is happening to a new version of express-handlebars module. To fix this pass the following runtime options into handlebars engine configuration.
first of all, type a following command in your terminal and hit enter:
npm install #handlebars/allow-prototype-access
and
npm install handlebars
after that write these code into your server.js file
const Handlebars = require('handlebars')
and
const {allowInsecurePrototypeAccess} = require('#handlebars/allow-prototype-access')
then add this line:
handlebars: allowInsecurePrototypeAccess(Handlebars)
in your setup view engine.
I also faced the same problem while using mongoose with hbs, but I was using async / await instead of promises. So I tried .lean() method
like #Boniface Dennis said that solved my problem.
For more information please checkout link
//the syntax goes like this
const messages = await Messages.find({}).lean();

AngularJs - Use External controller.js

Just started with Angular and trying to make this work.
I would like to display the name in the <p></p>, but it shows {{ name }}.
ASPX:
<html ng-app="myApp">
<head runat="server">
<script src="Assets/Vendor/angularjs-v1.2.28.js"></script>
<script src="App/app.js"></script>
<script src="App/controllers.js"></script>
</head>
<body ng-controller="myCtrl">
<p>{{ name }}</p>
</body>
</html>
app.js:
var app = angular.module('myApp','myCtrl');
controllers.js:
var controller = {};
controller.myCtrl = function ($scope) {
$scope.name = "abcd";
}
EDIT: I have changed the order of loading the script files and updated this query.
This is the error I see in console - Uncaught Error: [$injector:modulerr]
You've not correctly put the order of the scripts. Rather put app.js in front of controller.js. Now you're getting the error: var app is not defined.
[Addition]
Furthermore, you're trying to inject myCtrl which is no object. So changing var controller to var myCtrl would probably work.
Better would be to use something as described here: https://docs.angularjs.org/guide/controller
app.controller('myCtrl', ['$scope', function($scope) {
$scope.name = "abcd";
}]);
Few things here:
1 - myCtrl is not a dependent module. So, you don't need it when defining the myApp module:
angular.module('myApp',[]);
2 - Order of scripts, as described by #Highmastdon.
3 - When defining the controller, you can use the myApp module:
angular.module('myApp').controller('myCtrl', function($scope) {
$scope.name = 'abcd';
});

Handlebars partial display name instead of template in loopback

I have a wired problem of partial showing the name instead of the template itself in loopback. For some reason the partials are not getting registered. Following is my code ... I am sure I am missing something but not able to quite figure it out. All help the appreciated. I am using express-handlebars as the bridge between loopback and handlebars
In server.js, I have the following code
var handlebars = require('handlebars');
var exphbs = require('express-handlebars');
var hbs = exphbs.create({
defaultLayout : '',
helpers : {},
extname : 'handlebars'
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('views', __dirname + '/../client/views');
Following is my express router code ...
router.get('/', function(req, res) {
res.render('index', {
partials: {
mypartial : 'awesomepartial'
},
});
});
... and the partial tag from index page. The partial page is just plain html code
{{> mypartial}}
.... when the index template gets executed, instead of seeing the text from awesomepartial.handlebars template (which resides in same directory as index.handlebars) I see following text
awesomepartial
What could I be doing wrong? Why is handlebars sending the partial name back instead of template code. I tried various combinations which makes me believe that path may not be a problem.
Following is the working code ...
var handlebars = require('handlebars');
var exphbs = require('express-handlebars');
var hbs = exphbs.create({
defaultLayout : '',
helpers : {},
partialsDir : __dirname + '/../client/views',
extname : 'handlebars'
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('views', __dirname + '/../client/views');
router.get('/', function(req, res) {
res.render('index', {
mypartial : 'awesomepartial'
});
});
{{> (lookup . 'mypartial'}}
I believe you need to use a dynamic partial which is done like so:
{{> (mypartial)}}
basically just wrapping the variable with parens. See docs for "Dynamic Partials" here: http://handlebarsjs.com/partials.html

Resources