Handlebars Template is not rendered - javascript

Hey I am completly new to Handlebars.js and almost new to JavaScript itself.
So I tried to go through the following tut: http://coenraets.org/blog/phonegap-tutorial/
I completed Part 5 and wanted to test the app in the browser. But the page ist blank. Does the browser recognize handlebars.js by himself and renders the handlebars template automatically? Or why do I receive a blank page?
I hope the questions is not to basic, however I have no clue how to proceed or where my error lies.
index.html:
<html>
<body>
<script id="home-tpl" type="text/x-handlebars-template">
<div class='header'><h1>Home</h1></div>
<div class='search-bar'><input class='search-key' type="text"/></div>
<ul class='employee-list'></ul>
</script>
<script id="employee-li-tpl" type="text/x-handlebars-template">
{{#.}}
<li>{{this.firstName}} {{this.lastName}}<br/>{{this.title}}</li>
{{/.}}
</script>
<script src="lib/jquery-1.8.2.min.js"></script>
<script src="js/storage/memory-store.js"></script>
<script src="js/main.js"></script>
<script src="lib/handlebars.js"></script>
</body>
main.js:
var app = {
findByName: function() {
var self = this;
this.store.findByName($('.search-key').val(), function(employees) {
$('.employee-list').html(self.employeeLiTpl(employees));
});
},
initialize: function() {
var self = this;
this.store = new MemoryStore(function() {
self.renderHomeView();
});
this.homeTpl = Handlebars.compile($("#home-tpl").html());
this.employeeLiTpl = Handlebars.compile($("#employee-li-tpl").html());
},
renderHomeView: function() {
$('body').html(this.homeTpl());
$('.search-key').on('keyup', $.proxy(this.findByName, this));
},
showAlert: function (message, title) {
if (navigator.notification) {
navigator.notification.alert(message, null, title, 'OK');
} else {
alert(title ? (title + ": " + message) : message);
}
},
};
app.initialize();
I get the follwoing errors in main.js:
ln. 15: Uncaught ReferenceError: Handlebars is not defined
ln 20. :Uncaught TypeError: Object # has no method 'homeTpl'
Kind regards,
Snafu

Move your handlebars.js above your main.js script tags.

I did the above change...which seemed quite logical. However, the above solution didn't work.
I added the below
this.homeTpl = Handlebars.compile($("#home-tpl").html());
this.employeeLiTpl = Handlebars.compile($("#employee-li-tpl").html());
in the renderHomeView function... Works well for me..... :)
renderHomeView: function() {
this.homeTpl = Handlebars.compile($("#home-tpl").html());
this.employeeLiTpl = Handlebars.compile($("#employee-li-tpl").html());
$('body').html ( this.homeTpl());
$('.search-key').on('keyup', $.proxy(this.findByName, this));
}

Related

How to pass an object to an module in require.js?

I have these js files:
main.js:
requirejs(['app']);
app.js:
define(['messages'], function (messages) {
alert(messages.getHello());
});
messages.js:
define(['global'],function () {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
global.js:
define(function () {
var stateObj = {hello:"test!"};
return {
getObj: function () { return stateObj; }
};
});
and index.html as:
<!DOCTYPE html>
<html>
<head>
<!-- Include the RequireJS library. We supply the "data-main" attribute to let
RequireJS know which file it should load. This file (scripts/main.js) can
be seen as the entry point (main) of the application. -->
<script data-main="scripts/main" src="lib/require.js"></script>
</head>
<body>
<h1>Example 2: load module using explicit dependency syntax</h1>
</body>
</html>
However when I open index.html, I get the below error in console:
Uncaught ReferenceError: global is not defined messages.js
where I'm making mistake?
You just need to set global as an argument to messages.js' function. requirejs will pass it in for you.
messages.js:
define(['global'],function (global) {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
This has the neat side effect that it is impossible to reference a module without declaring it as a dependency.

Uncaught ReferenceError: jQuery is not defined

I don't see why I would get this, code below:
<head>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js" type="text/javascript"></script>
<script>
var json1 = {
text: "After first paragraph"
};
var first_content_added = false;
$(function() {
$(".learn-more").on("click", function() {
$.getJSON("json_info.json", function(data) {
appendContentToFirstP(data.reviews[0].about.moreinfo);
});
});
});
function appendContentToFirstP(content) {
if (first_content_added) {
return;
}
var after_first_p = $('<p class="more-info" />');
after_first_p.text(content);
$(".first").append(after_first_p);
first_content_added = true;
}
</script>
</head>
What would be causing the error?
My initial thought is the error is because I have not imported JQuery, but I have. It's inside the script tag at the top.
You haven't included jQuery, you've only included the plugin jQuery.color.
Reference it before jQuery.color:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
write before that color js like this
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js" type="text/javascript"></script>

Node,express,jade rendered pages doesn't data-bind with knockout.js

I'm running a Node server with express which renders jade. I'm trying to make my client side use knockout.js but the view never updates... I don't get any errors in the console and I just can't figure out what is wrong.
Page:
extends layout
block content
script(src='knockout/knockout-2.2.1.debug.js', type='text/javascript')
script(src='js/app.js', type='text/javascript')
p Hi,
strong(data-bind="text: firstName")
rendered html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<script src="knockout/knockout-2.2.1.debug.js" type="text/javascript"></script>
<script src="js/app.js" type="text/javascript"></script>
<p>Hi,<strong data-bind="text: firstName"></strong></p>
</body>
</html>
app.js:
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
}
ko.applyBindings(new AppViewModel());
is there something I'm missing here or is it just not possible to make this happen with Node.js and express?
You need to make sure you call ko.applyBindings() after the DOM has already been loaded.
Either wrap the code in app.js in window.onload, in jQuery's ready() function, or move your script tag to be below <p>Hi,<strong data-bind="text: firstName"></strong></p>.
// this is my js file
(function () {
//START THE APP WHEN DOCUMENT IS READY
$(function () {
function AppViewModel() {
var self = this;
self.firstName = "Hamza";
// self.lastName = ko.observable("Bertington");
}
ko.applyBindings(new AppViewModel());
});
})();

jsdom not loading external resources

I can't seem to get jsdom to execute external scripts and I can't seem to find any concrete examples. I don't get any error when I call my testing function, but nothing happens.
This is my code:
var window = jsdom.jsdom(body).createWindow();
jsdom.jQueryify(window, './lib/jquery.js', function () {
console.log(window.$("#a1").text());
window.testing();
console.log(window.$("#a2").text());
});
This is the html its loading:
<html>
<head>
<script type="text/javascript" src="stuff.js"></script>
</head>
<body>
Hi there
<div id="a1">
</div>
<div id="a2">
</div>
</body>
</html>
My testing function:
function testing() {
var a2 = document.getElementById("a2");
a2.innerHTML = 'Second div';
console.log("executed");
}
Check out the jsdom docs
Try this before the rest of your code:
require('jsdom').defaultDocumentFeatures = {
FetchExternalResources : ['script'],
ProcessExternalResources : ['script'],
MutationEvents : '2.0',
QuerySelector : false
}
var window = jsdom.jsdom(body).createWindow();
jsdom.jQueryify(window, './lib/jquery.js', function () {
console.log(window.$("#a1").text());
window.testing();
console.log(window.$("#a2").text());
});
/fyi #node.js IRC welcomes you: http://bit.ly/nodeIRC

javascript objects cant see each other? :: google chrome extension

i have two files
one called stats.js
one called storage.html
in stats.js in contains
var stats = {
myFunc : function() {
//do something
}
}
in storage.html I have
<html>
<head>
<script src="stats.js"></script>
<script>
$(document).ready(function() {
stats.myFunc();
});
</script>
</head>
</html>
But I get
Uncaught TypeError: Cannot call method 'myFunc' of undefined
Update
Ok so that was a really simplified example.
The basics of it are,
This is a google chrome extension, So you will see some code specific to that.
Here is the literal pages concerned:
Popup.html
<html>
<head>
<title>Extension</title>
<script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script src="js/popup.js"></script>
<script src="js/statsapi.js"></script>
<link type="text/css" rel="stylesheet" href="css/popup.css" />
</head>
<body>
<div id="content">
</div>
</body>
</html>
popup.js
$(document).ready(function() {
if(background.storage.get('firstRun') == null)
background.initialize();
if(background.storage.get('metaExpire') >= Date.parse(Date()))
background.updateMeta();
$('#content').append(read_object(stats.getMetaData()));
});
function read_object(object){
var $obj = $('<div />');
for(var o in object) {
$obj.append(o+' : ');
if(typeof(object[o]) == 'object' && object[o] != null)
$obj.append(read_object(object[o]));
else
$obj.append(object[o]+'<br />');
}
return $obj;
}
Manifest.json
{
"name": "Halo Reach: Stats",
"description": "This extension allows you to keep track of your own, and your friends Halo Reach Stats.",
"version": "1.0.0.1",
"permissions": [
"http://www.bungie.net/"
],
"icons": {
"128": "images/logo/logo128.jpg",
"64": "images/logo/logo64.jpg",
"32": "images/logo/logo32.jpg",
"16": "images/logo/logo16.jpg"
},
"browser_action": {
"default_title": "Open Stats",
"default_icon": "images/logo/logo32.jpg",
"popup": "popup.html"
},
"background_page": "background.html"
}
statsapi.js
var background = chrome.extension.getBackgroundPage();
var apikey = background.storage.get('apikey');
var gamertage = background.storage.get('gamertag');
var page = '0';
var stats = {
getMetaData : function() {
var url = 'http://www.bungie.net/api/reach/reachapijson.svc/game/metadata/'+apikey;
console.log(url);
$.ajax({
url: url,
success: function(data) {
return data;
}
});
},
meta : {
read : function(param) {
var meta = background.storage.get('metaData');
}
}
};
Background.html
<html>
<head>
<script src="js/statsapi.js"></script>
<script>
var storage = {
set : function (key, value) {
window.localStorage.removeItem(key);
window.localStorage.setItem(key, value);
},
get : function (key) {
return window.localStorage.getItem(key);
},
clear : function () {
window.localStorage.clear();
}
};
function updateMeta() {
var meta = stats.getMetaData();
if(meta['status'] == 0){
storage.set('metaData', JSON.stringify(meta));
storage.set('metaExpire', Date.parse(Date())+900000);
}
}
function initialize() {
storage.set('apikey', '***');
storage.set('gamertag', 'The Hailwood');
updateMeta();
}
</script>
</head>
</html>
When the extension is invoked it calls popup.html
and the document ready javascript is invoked.
The check for first run fails,
so it calls initialize() in background.html
But this is where the error occurs.
the actual error is
Uncaught TypeError: Cannot call method 'getMetaData' of undefined.
So why can it not see the stats class?
its not a script include problem as if the path is wrong for the statsapi.js I get
Uncaught ReferenceError: stats is not defined.
The issue seems to be with the var stats {} as if under that I have a function called test() I can call that fine :/
Hmm,
is there an issue because it is an external stylesheet?
I suspect the error lies somewhere else - these are my examples:
mark#localhost:~/ccsite$ cat cat.js
var stats = {
myFunc : function() {
alert('wtf');
}
}
mark#localhost:~/ccsite$ cat hat.htm
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="cat.js"></script>
<script>
$(document).ready(function() {
stats.myFunc();
});
</script>
</head>
</html>
Viewing hat.htm in either FF, IE6 or Chrome produces the alert, 'wtf'. As written you'd get $ is undefined, since it's not including jQuery of course, so I added that.
So, your problems likely are elsewhere. I assume this is a simplified example - what else is going on in your page?
This is because there is some syntax error in your code. I had same problem. I opened my background.html page in fire fox with fire-bug plug-in enabled. Fire-bug console should me the error, I fixed and it is working now.
I have suspicions that it's because you include js/statsapi.js script into both your popup and background page, so it gets confused which stats you are referring to as you have 2 of them in the popup - one included through script tag and another one loaded from background page after you call chrome.extension.getBackgroundPage()

Categories