Funny behavior of Underscore template [duplicate] - javascript

This question already has answers here:
Underscore template throwing variable not defined error
(2 answers)
Closed 7 years ago.
I try to pass data immediately to template call:
var compiled = _.template('template code there', {params: 123})
And regards to specs the variable 'compiled' must be ready to use as HTML markup.
But! I got a function..
It's really strange for me.. I ran this code at plnkr.co, and it gave expecting result, but locally it's not working as expected.
p.s. In my example I use bower to download scripts
<script src="../scripts/vendor/jquery/dist/jquery.js"></script>
<script src="../scripts/vendor/underscore/underscore.js"></script>
<script src="../scripts/vendor/backbone/backbone.js"></script>
...
var list = "<%= ... %>";
var compiled = _.template(list, {data : ['one', 'two']});
alert(compiled); // got function !
Can anybody explain this?
P.S. worked example - http://jsfiddle.net/xm6ymxoj/
and I can't reproduce this simple code locally on my machine, as result I receive a function (in alert).

_.template(templateString, [settings]) (see docs) compiles a string to a template. This template is a function that can then be rendered to HTML with some given data.
From the docs:
var compiled = _.template("hello: <%= name %>");
compiled({name: 'moe'});
=> "hello: moe"
EDIT: So in your example you should use:
var list = "<%= ... %>";
var compiled = _.template(list);
var html = compiled({data: ['one', 'two']})

It's many code examples in network something like this one:
var c_markup = _.template("Hello <%=user%>!", { user: "MyName" });
But as I understand this code is obsolete, and not worked now.
We need to pass parameters to prepared function call:
var c_markup = _.template("Hello <%=user%>!");
c_markup({ user: "MyName" });
This moment was confused me. Hope this can helps someone.

Related

Angularjs Controller Error [$controller:ctrlreg]

I am working on a website and it's running fine (online). I used angularjs for the javascript. I already minified all my angularjs code. But now, I put some new files called app-v2.js which is a javascript file. But, the new files I added seems not working. When I see the console of my browser it says like this Error: [$controller:ctrlreg] http://errors.angularjs.org/1.6.1/$controller/ctrlreg?p0=v2-ctrl. That errors mean that the controller v2-ctrl was not found/defined. But when i double check my files and codes it was there. Why is this happening? Here is my app-v2.js code:
(function(){
'use strict';
app.controller('v2-ctrl',['$scope','$http','$sce','$window','$timeout','$location','$route','$document', function($scope,$http,$sce,$window,$timeout,$location,$route,$document){
$scope.getAwards = function(){
$http.post('angular?ng=awards',{}).then(function(response){
$scope.awards = response.data;
for(var i = 0; i<response.data.length;i++){
response.data[i].award_title = response.data[i].award_title.replace(/&/g, '&');
}
$scope.awards = response.data;
});
};
})();
NOTE: The app was already defined on the another js file.
I hope someone can help me. I'm really stucked.
HEY: You can see actual code here
Click this

Node JS FREEZES when _.template is evaluated and a ReferenceError happens

I've found a weird behavior with http://underscorejs.org/ in Node JS:
When a reference error happens when we evaluate a template function, Node JS will FREEZE!
Examples:
EXAMPLE 1: HAPPY DAY SCENARIO:
var template = "<%= test %>";
var compiledTemplate = _.template(template);
var result = compiledTemplate({test:1});
console.log(result);
//RESULT (both BROWSER and NODE JS):
//1
EXAMPLE 2: COMPILE ERROR SCENARIO (an extra = before closing):
var template = "<%= test =%>";
var compiledTemplate = _.template(template);
var result = compiledTemplate({test:1});
console.log(result);
//RESULT (both BROWSER and NODE JS):
//uncaughtException { [SyntaxError: Unexpected token )]
EXAMPLE 3: EVALUATION ERROR SCENARIO (test is not defined):
var template = "<%= test %>";
var compiledTemplate = _.template(template);
var result = compiledTemplate({no_test_defined:1});
console.log(result);
//RESULT (BROWSER):
//Uncaught ReferenceError: test is not defined
//RESULT (NODE JS):
//Node JS FREEZES - nothing happens, neither and error is thrown, neither the flow goes on
Anybody had ever get a similar behavior? Any hints for solution? I really need to catch the exception in a try/catch block...
Cheers!
Oscar
After some troubleshoot I could finally found what was the problem.
When I run this inside Webstorm DEBUGGER, this behavior happens (Node JS FREEZES). When I run it in command line, i works as expected. I will search in Webstorm issues if hey have something.
Cheers!!!!
Oscar

What is the Syntax to get Thymeleaf ${pageContext.request.contextPath}

I have searched hard for a syntax like the JSTL one ${pageContext.request.contextPath},
I did made a javascript code to change the action attribute on the form to call the edit method on the spring controller so, the problem is the below code dont work without calling the Context first like ${pageContext.request.contextPath}/edit.html
<script th:inline="javascript">
function edit() {
document.getElementById("user_form").action = "/edit.html";
}
</script>
so what is the Syntax to call Thymeleaf context path?
In Thymeleaf the equivalent of JSP's ${pageContext.request.contextPath}/edit.html would be #{/edit.html}
Check out this part of the Thymeleaf documentation for more details
In your case you would write :
<script th:inline="javascript">
function edit() {
var link = /*[[#{/edit.html}]]*/ 'test';
document.getElementById("user_form").action = link;
}
</script>
The /*[[ - ]]*/ syntax is used by Thymeleaf to evaluate variables used by Javascript, without breaking the script if that where to be statically loaded. Check out this part of the documentation for more details
My solution for Thymeleaf and jQuery is below.
Use ${#httpServletRequest.getContextPath()} in Thymeleaf to write the context path in the meta element:
<meta name="_ctx" th:content="${#httpServletRequest.getContextPath()}" />
and in jQuery, use $.ajaxPrefilter() to prepend context path to all jQuery AJAX requests:
var _ctx = $("meta[name='_ctx']").attr("content");
// Prepend context path to all jQuery AJAX requests
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
if (!options.crossDomain) {
options.url = _ctx + options.url;
}
});
Just in case anybody else stumbles upon this question looking for what I originally had been...setting a context path variable for the root of the page inside the Thymeleaf page to carry over to an external JQuery page. Here is how it worked for me...same as above just left blank...
Old way with JSP
<script >var contextRoot = "${pageContext.request.contextPath}"; </script>
New way with Thymeleaf
<script th:inline="javascript"> var contextRoot = /*[[#{/}]]*/ ''; </script>
and a link with more information...
http://forum.thymeleaf.org/JSESSIONID-in-td3386826.html
(also depending on the IDE, I set the script over two+ lines as opposed to the same line of the code number.)
Try this:
var BASE_CONTEXT_PATH = $('meta[name=context-path]').attr("content");
BASE_CONTEXT_PATH = BASE_CONTEXT_PATH.substr(0, BASE_CONTEXT_PATH.length - 1);
<meta name="context-path" th:content="#{/}"/>

How to check if an object exists when passing variables with jade

In Jade you can pass through an object to the client like this
Route:
res.render('mypage', {
title: 'My Page',
myobject : data
});
Jade Template:
extends layout
block navbar
include includes/navbar
block top
include includes/top
block content
script(src='/js/controllers/test-controller.js')
script.
var clientobj = !{JSON.stringify(myobject)}
But what if myobject does not exist? It seems like it would be the simplest thing to check if this object exists before using it (and therefore only try to define the var clientobj if it does) but I am banging my head here trying to get make this happen.
Eg:
res.render('mypage', {
title: 'My Page'
});
Will currently break the given template, there has to be some syntax to make this code more resilient, surely..
The following code snippet should help.
script
if myobject
| var clientobj = !{JSON.stringify(myobject)}
Please note that you should not put . (dot) at the end of script element. Otherwise if myobject ... will be considered as text and not Jade code.
Alternatively this should work too:
script.
var clientid = #{myobject ? JSON.stringify(myobject) : "undefined"};
In that case you will get following HTML code and you will have to handle clientid as undefined in your JavaScrip code in a page.
<script>var clientid = undefined;</script>
I hope that will help

How to evaluate a HTML DOM object (like "document") in RubyRacer

RubyRacer allows me to easily execute javascript code within a ruby environment, like so:
cxt = V8::Context.new
wanted_output = cxt.eval(whatever_javascipt_code)
How does one have to do it when objects like "document" are involved, like for example in the follwing code snippet?
(In other words, how can I generate the output of "document.write" in this case?)
<script language="javascript" type="text/javascript">
A="some_string";
B="some_other_string";
C="";
for(j=0;j<B.length;j++){
C+=A.charAt(B.charCodeAt(j)-48);
}document.write(C);
</script>
Simply evaluating the script above would result in the error message:
"V8::JSError: document is not defined"
Thanks a lot for any hints!
Assuming that the variable 'script' contains the javascript code mentioned above:
cxt = V8::Context.new
script.insert(0, "output=''")
document_write_count = script.scan('document.write(').count
remaining = script
document_write_count.times do |i|
document_write_clause_content = remaining.partition('document.write(')[2].partition(')')[0]
document_write_clause = "document.write(#{document_write_clause_content})"
document_write_clause_replacement = "output+=#{document_write_clause_content}"
script.gsub!(document_write_clause, document_write_clause_replacement)
remaining = remaining.rpartition(document_write_clause_replacement)[2]
end
script.insert(-1, "output;")
wanted_output = cxt.eval("#{script}")

Categories