use client-side js variable in pug - javascript

Can I somehow use client-side javascript variables in pug file, for loop in objects or in arrays? Like I have some array in client-side js file: var someArray, and I wont too send this array in pug file for loop into it... is it possible?

If you are running pug client side (as per the browser support section of the homepage), then you just pass the value into the compiled template.
var locals = {
someName: someArray
}
var fn = pug.compile('string of pug', options);
var html = fn(locals);
If you are running pug server side, then you will have to make multiple requests to the server as described in What is the difference between client-side and server-side programming?.

Related

Send arguments to use function in JS Use API | AEM 6.5

I am trying to get the url in my Javascript file. But seems like window.location work in JS Use API neither. So I was trying to send the URL as an argument but that's failing with an error.
My JS code:
"use strict";
use(function () {
var url = this.url;
/other code/
});
My HTML code:
<sly data-sly-use.item="'myfile.js' # url=value">
HTL/Sightly is a server-side template language. The scripts (including JS Use Objects) are compiled and ran once, when the page is rendered. To get the current URL/location you can leverage SlingHttpServletRequest#getRequestPathInfo. The current request is available as request as part of the HTL Global Objects.
Also, regarding getting errors when using <sly data-sly-use.item="'myfile.js' # url=value">, that's most probably because value is not defined as a variable name in the HTL server-side rendering context. Using <sly data-sly-use.item="'myfile.js' # url='https://www.test.com/'"> should work.

Get json from flask using an external js file

I have a flask server spitting out json data converted from pandas dataframe which look like:
[{'name': 'FBtr0075557',
'score': '164.00'},
{'name': 'FBtr0075557',
'score': '162.00'}]
The python code I'm using to convert the dataframe to json and serve in flask is:
result = df.to_json(orient="records")
parsed = json.loads(result)
return render_template('mirtar.html', targets=json.dumps(parsed))
When I use internal javascript, the data is parsed without any error:
<script type="text/javascript">
const targets = {{ targets|tojson }};
const entries = JSON.parse(targets);
console.log(entries);
</script>
However when I try to do the same using an external JS script, I get an error
Uncaught SyntaxError: Unexpected token { in JSON at position
From what I understand, the line const targets = {{ targets|tojson }}; in the external javascript doesn't behave the same way as in internal and the first '{' of the line is considered as an error.
I'm sure this is a very basic problem and there must be an easy way to do it that I have definitely missed.
Jinja syntax is only parsed in flask html templates, not externally loaded JS assets: because it's the python app doing the parsing, and in a deployed environment you'd typically serve static assets with a webserver like nginx.
The quickest way to sort this might be with this method where instead you use a data attribute within an HTML element. This appreciates that you're passing data to the template as an argument to render_template, so the data is present in the template at page load.
In your case this might look like
<!-- a hidden tag -->
<input type='hidden' id='targetid' data-thetargets='{{ targets|tojson }}' />
Then in your javascript load it up with:
var targets = JSON.parse(document.getElementById("targetid").dataset.thetargets);

Accessing MVC server side variable in Javascript

I'm moving one of our web applications from Drupal to an ASP.net MVC Web Application.
One of the Drupal functions gets some data from a web service and converts it to a JS Array, as follows:
foreach ($xml_result->JobList->JobDetail as $job_detail) {
// dsm((array)$job_detail);
$open_job_details[] = array("east"=>(string)$job_detail->Easting,"north"=>(string)$job_detail->Northing, "duedate"=>(string)$job_detail->openDate);
}
//dsm($open_job_details);
$open_jobs_data = json_encode($open_job_details);
drupal_add_js(array('open_jobs' => array('open_newjobs' => $open_jobs_data)), 'setting');
In the Javascript file, it is accessed using;
var openJobsData = JSON.parse(Drupal.settings.open_jobs.open_newjobs);
Is there a simple way to access a server side variable in the JS file in .NET? I can call the web service and get the relevant data from the XML file but not sure how to access it in the JS file.
Thanks
You can use Strongly Typed view to create cshtml page
if you want to access JSON object
View1.cshtml
#model mvcApplication1.Models.model1
#{
var serializer = new
System.Web.Script.Serialization.JavaScriptSerializer();
serializer.MaxJsonLength = int.MaxValue;
var jsonModel = serializer.Serialize(Model);
}
var JsonData = #Html.Raw(jsonModel); // declare a javascript variable and use it
if you want to access server variable at cshtml page
just use # to access server-side variables
after getting the value you can use javascript variable in another js file
Declare your javascript variable outside
$(document).ready(function()
{}
or before using the variable
you can use that variable in Javascript file.

Server Side Templating Engine to render javascript

My use case is that I have portions of js code that I would like to render based on some user permissions, with server side language being PHP.
Now I am currently using the Fat Free Framework, but even in other frameworks like laravel, I have only been able to find templates that template HTML.
I know I can use the templating engines that exist to just have conditional template logic to print a <script> tag given certain user permissions, but I haven't found any examples of how to do the following in a .js file
Example:
PHP:
$visible = ['section1' => true, 'section2' => true];
//this just renders the js file
render('test.js', ['visible' => $visible]);
test.js:
`//this is some kind of templating format`
{{if(isset($visible['section1']))}}
var a = 'Gin';
function sectionA(){
//do something
}
{{endif}}
{{if(isset($visible['section3']))}}
var b = 'Rum';
function sectionB(){
//do something
}
{{endif}}
The result would be that test.js would be rendered as
var a = 'Gin';
function sectionA(){
//do something
}
Alright, so after some playing around, I've figured out a solution. when building the html, you can echo a script that has a src of whatever resource you want. on the server side, respond to the javascript src route by rendering a js file (using the templating engine) that has the templating markups in it, and things will work as I wanted them to :)

Accessing Express.js local variables in client side JavaScript

Curious if I'm doing this right and if not how you guys would approach this.
I have a Jade template that needs to render some data retrieved from a MongoDB database and I also need to have access to that data inside a client side JavaScript file.
I'm using Express.js and sending the data to the Jade template as follows :
var myMongoDbObject = {name : 'stephen'};
res.render('home', { locals: { data : myMongoDbObject } });
Then inside of home.jade I can do things like :
p Hello #{data.name}!
Which writes out :
Hello stephen!
Now what I want is to also have access to this data object inside a client side JS file so I can manipulate the Object on say a button click before POSTing it back to the server to update the database.
I've been able to accomplish this by saving the "data" object inside a hidden input field in the Jade template and then fetching the value of that field inside my client-side JS file.
Inside home.jade
- local_data = JSON.stringify(data) // data coming in from Express.js
input(type='hidden', value=local_data)#myLocalDataObj
Then in my client side JS file I can access local_data like so :
Inside myLocalFile.js
var localObj = JSON.parse($("#myLocalDataObj").val());
console.log(localObj.name);
However this stringify / parsing business feels messy. I know I can bind the values of my data object to DOM objects in my Jade template and then fetch those values using jQuery, but I'd like to have access to the actual Object that is coming back from Express in my client side JS.
Is my solution optimal, how would you guys accomplish this?
When rendering is done, only the rendered HTML is send to the client. Therefore no variables will be available anymore. What you could do, is instead of writing the object in the input element output the object as rendered JavaScript:
script(type='text/javascript').
var local_data =!{JSON.stringify(data)}
EDIT: Apparently Jade requires a dot after the first closing parenthesis.
I do it a little differently. In my contoller I do this:
res.render('search-directory', {
title: 'My Title',
place_urls: JSON.stringify(placeUrls),
});
And then in the javascript in my jade file I use it like this:
var placeUrls = !{place_urls};
In this example it's used for the twitter bootstrap typeahead plugin. You can then use something like this to parse it if you need to :
jQuery.parseJSON( placeUrls );
Notice also that you can leave out the locals: {} .
Using Jade templating:
If you are inserting #Amberlamps snippet of code above an included static HTML file, remember to specify !!! 5 at the top, to avoid having your styling broken,
in views/index.jade:
!!! 5
script(type='text/javascript')
var local_data =!{JSON.stringify(data)}
include ../www/index.html
This will pass in your local_data variable before the actual static HTML page loads, so that the variable is available globally from the start.
Serverside (using Jade templating engine) - server.js:
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.get('/', ensureAuthenticated, function(request, response){
response.render('index', { data: {currentUser: request.user.id} });
});
app.use(express.static(__dirname + '/www'));
You don't need to pass the locals variables in render call, locals variables are globals. On your pug file call don't put keys expression e.g #{}. Just use something like:
base(href=base.url)
where base.url is app.locals.base = { url:'/' };
Have you heard of socket.io? (http://socket.io/).
An easy way to access the object from express would be to open a socket between node.js and your javascript. This way data can be easily passed to the client side and then easily manipulated using javascript. The code wouldn't have to be much, simply a socket.emit() from node.js and a socket.on() from the client. I think that'd be an effective solution!

Categories

Resources