I know its been asked many times, I have looked at the answers and not sure where I am going wrong.
I have looked at the docs on Handlebarsjs and followed a tutorial and both times I am getting the same error.
<!DOCTYPE html>
<html>
<head>
<script src="handlebars-v1.3.0.js"></script>
<script src="jquery.min.js"></script>
<script src="test.js"></script>
</head>
<body>
<script id="header" type="text/x-handlebars-template">
div {{ headerTitle }} div
Today is {{weekDay}}
</script>
</body>
</html>
And this is my Javascript
var theData = {headerTitle:"name", weekDay:"monday"}
var theTemplateScript = $("#header").html();
var theTemplate = Handlebars.compile(theTemplateScript);
$(document.body).append(theTemplate(theData));
I keep on getting the following error and i am unsure why
Uncaught Error: You must pass a string or Handlebars AST to Handlebars.compile.
You passed undefined
You are running Handlebars.compile() before theTemplateScript is loaded into the DOM. Move your test.js down below the template script and you should be good to go.
Moving the scripts to the bottom of the page also worked for me.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script id="header" type="text/x-handlebars-template">
div {{ headerTitle }} div
Today is {{weekDay}}
</script>
<script src="handlebars-v1.3.0.js"></script>
<script src="jquery.min.js"></script>
<script src="test.js"></script>
</body>
</html>
As others have said, the problem is that you are running Handlebars.compile() before the TemplateScript is loaded into the DOM.
Putting your javascript calls in $(document).ready() you make sure all the html is loaded first.
var theData = {headerTitle:"name", weekDay:"monday"}
$(document).ready(function(){
var theData = {headerTitle:"name", weekDay:"monday"}
var theTemplateScript = $("#header").html();
var theTemplate = Handlebars.compile(theTemplateScript);
$(document.body).append(theTemplate(theData));
});
in my case i was trying to assign some value to more deeper steps therefore, i faced the error.
Before my code was
app.use(function (req, res, next) {
res.locals.partials.weather = {}; = getWeatherData();
next();
});
and the problem was
res.locals.partials.weather
after removing the layer partial my problem was gone.
and the final code is
app.use(function (req, res, next) {
res.locals.weather = getWeatherData();
next();
});
In my case I got the same error but the issue was a typo in the template script in the html page. I had 'prouct-template' should have been 'product-template':
<script id="prouct-template" type="text/x-handlebars-template">
...
</script>
Once I fixed the typo the error went away and page loaded ok.
A bit of modification is needed in JavaScript file. I had the same issue. In my code, I called "handlebars" from Views (following explanation is with respect to views).
Include following in initialize function(init) of View :
theTemplate = Handlebars.compile(theTemplateScript);
In render write the remaining code :
var theTemplate = Handlebars.compile(theTemplateScript);
$(document.body).append(theTemplate(theData));
The correct way is to precompile the Handler, Store in file and then assign it to theTemplate.
You're using Handlebars.compile() before the template script loads. One simple trick would do the work for you. Use the defer tag in your script so that the entire body loads before the script runs in your <head> tag.
<head>
<script src="" defer> </script>
</head>
Related
I'm playing around with Handlebars.js and trying to compile a small template. I am only using Handlebars.js and nothing more.
I am working locally on my computer, and not via any form of server.
my "html" looks like this. nothing special.
<!doctype html>
<html>
<head>
<script src="js/vendor/handlebars.min-4.0.4.js"></script>
</head>
<body>
<script id="menu-template" type="text/x-handlebars-template">
<h1>{{title}}</h1>
</script>
<section id="menu">
</section>
<script src="js/menu.js"></script>
</body>
</html>
And my JS is
var source = document.getElementById('menu-template').innerHTML;
var template = Handlebars.compile(source);
var data = {title: "test"};
document.getElementById('menu').innerHTML = template(data);
It seems that template() does not return anything, i don't get any result except what looks like a empty string.
And i have been playing around with this for a few hours and searching the internet for answers but no result.
Am i doing anything wrong here?
// Edit added the rest of the html page.
The code seems correct just make sure the Handlebars.js file is properly included before the existing script tag.
Ref for Handlebars CDN : https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.4/handlebars.js
I'm trying to understand how to modularize the Backbone ToDo tutorial
Originally everything is inside the same file, but if I try to extract to another file:
var TodoView = Backbone.View.extend({
...
});
then this throws an error:
var view = new TodoView({model: todo});
**Uncaught TypeError: undefined is not a function**
It's probably due to a scope issue, but I don't know how to create a reference inside the $(function() so I can create this new object inside the main function.
Assuming that your first code part is TodoView.js,
and your second code part is app.js.
Write your html file like this,
<html>
<head>
<script type="text/javascript" src="js/TodoView.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body>
// your dom
</body>
</html>
(Edited, at 2015-07-27)
sorry for my late reply.
how about this?
<html>
<head></head>
<body>
<!-- your dom -->
<script type="text/javascript" src="js/TodoView.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
In many case, most javascript codes are appended to just before </body>, so that javascript can use your dom!
You can use something like require.js to load your external files and manage dependancies.
Ok, the solution was to move the script references to the end of the body instead of inside the head tags.
I think that the reason is that TodoView.js is making use of templates that were defined in the body, and since the js file was being loaded before the body, the templates were not yet available.
I'm not sure if there has been a change in the way Meteor loads items, or the way it handles jquery, but I'm having an awful lot of trouble getting ckeditor to come up.
Main Template (Iron-router):
<template name="layout">
<head>
<script type="text/javascript" src="js/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="js/ckeditor/adapters/jquery.js"></script>
</head>
.....
</template>
Independent Editor Template:
<template name="editor">
<div class="editor_container">
<textarea class="editor"></textarea>
</div>
</template>
Ckeditor located at public/js/ckeditor, any time I try to do the Template.editor.rendered() technique, or even just trying to type $('.editor').ckeditor(); into the console, I get an error of:
$('.editor').ckeditor();
VM48825:2 Uncaught TypeError: undefined is not a function
Any ideas?
Try taking the <head> section out of the layout template. Reading here I believe the <head> section is treated specially be meteor (see: http://docs.meteor.com/#/full/structuringyourapp) and that it being inside a template may be causing the JS to actually not be loaded. Just a guess though.
<head>
<script type="text/javascript" src="js/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="js/ckeditor/adapters/jquery.js"></script>
</head>
<template name="layout">
.....
</template>
You can use IRLibLoader from iron:router into the onBeforeAction like this.
Router.route('/editor', {
name: 'editor',
template: 'layout',
onBeforeAction: function () {
var ckEditor = IRLibLoader.load('/js/ckeditor/ckeditor.js');
var adapter = IRLibLoader.load('/js/ckeditor/adapters/jquery.js');
if(ckEditor.ready() && adapter.ready()){
console.log('The 2 JS just finish load');
this.next(); // Render the editor page
if(Meteor.isClient){
Template.editor.rendered = function(){
$('.editor').ckeditor();
console.log("loading coeditor when template fully rendered");
}
}
}
}
});
Alternative on the main layout you can use this.
<head>
<script type="text/javascript" src="js/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="js/ckeditor/adapters/jquery.js"></script>
</head>
<template name="layout">
{{> yield}}
</template>
<template name="editor">
<div class="editor_container">
<textarea class="editor"></textarea>
</div>
</template>
And do the same rendered function
Template.editor.rendered = function(){
$('.editor').ckeditor();
//or make a little delay (1sec)
Meteor.setTiemout(function(){
$('.editor').ckeditor();
},100)
}
There are several problems with your code :
You can't put <head> sections inside another template, it must be done outside all templates.
The path to your JS files are broken, you must prepend a slash to them to reference files in the public directory.
Loading scripts in <head> sections is not a good idea because they will be loaded when your app first loads for every user, even if they never use the editor.
Here is a solution where we load every scripts asynchronously using jQuery promises when the editor template is rendered, and only then initialize the CKEditor.
Template.editor.rendered=function(){
var template=this;
$.when(
$.getScript("/js/ckeditor/ckeditor.js"),
$.getScript("/js/ckeditor/adapters/jquery.js")
).done(function(){
template.$(".editor").ckeditor();
});
};
How do we define different javascript files for different view pages in play framework??
One way is to=>
#main(title, """
#*JS CODE*#
"""{
//Template Codes
}
And in main template, use it like=>
#(title,stringJS){
<script>
#Html(stringJS)
</script>
}
But what if the JS code is to be used in not all pages but selected few, the dev can't copy the JS code in every relative view page.In my case all the javascripts are loaded on the footer, which is a seperate template.
How do we solve this problem??
Any help is appreciated, thank you!
It's described in the Common templates use cases doc , section : 'moreScripts and moreStyles equivalents'
In very short it works like this (view)
#moreScripts = {
<script type="text/javascript">alert("hello !");</script>
}
#moreStyles = {
<style>background: pink;</style>
}
#main("Title", moreScripts, moreStyles){
Html content here ...
}
and in main.scala.html start with:
#(title: String, moreScripts: Html = Html(""), moreStyles: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>#title</title>
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/main.css")">
#moreStyles
<script src="#routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
#moreScripts
</head>
<body>
#content
</body>
</html>
I came up with my solution,thanks to this Helpful SO post, what I did was:
#main(title, """
#*NO JS CODE, but declaration itself*#
<script src="/assets/javascripts/libs/main.js" type="text/javascript"></script>
<script src="#routes.Assets.at("javascripts/libs/main.js")" type="text/javascript"></script>//Doing this gives out errors, so I had to hardcode the "src" location
"""{
//Template Codes
}
If there is more efficient way to solve this issue, ideas are welcome, because hard-coding src isn't an efficient way of dealing with this issue, imo.
I'm looking to use Backbone.js with a namespaced underscore library. Does anyone know how I can tell Backbone to refer to say, underscore and not _
Thanks!
Matt
As of today (version 0.5.3) Backbone isn't ready for this in it self but it can be done:
You need to put your script tags requesting underscore.js and backbone.js first/early among your script tags, and do your _.noConflict() in a script between the underscore,backbone scripts and the rest of the script loading. Here's a schematic version:
<!DOCTYPE html>
<html>
<head>
<title>Labbo</title>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
<script>
var underscore = _.noConflict();
</script>
<script>
// In it's own script tag for readability
console.log('_ object: ', _);
console.log('"underscore" object: ', underscore);
var m = new Backbone.Model({});
console.log('Dummy backbone model: ', m);
</script>
<!-- Load your other scripts. From here on the '_' global isn't defined -->
<!-- any more. -->
<!-- <script src="your_other_scripts.js"></script> -->
</head>
<body>
Open Developer Tools / Firebug and check the output in the console.
</body>
</html>
(Couldn't put this on jsfiddle beacuse to demo you need control over excactly where the script tags go).