Jade/Pug - appending to a class name - node.js

Hello I have a unique id in an object and I want to append it to a class name. I am trying to do something like the following but it isn't working:
myJadeFile:
.googleChartContainer-#{attendanceAnalytics.uid}
myRoute.js:
res.render('./edu/school_dashboard_elementary', { attendanceAnalytics:attendanceChart });
I suppose I could create a class name in my route and send it as a variable with something like:
var className = '.googleChartContainer-attendanceChart.uid}';
res.render('./edu/school_dashboard_elementary', { attendanceAnalytics:attendanceChart, attendanceClassName:className });
and then in the jade file:
#{attendanceClassName} //- output is .googleChartContainer-someUid?
I was wondering if there was a way to get the first approach to work correctly, or if there is another preferred way.
Thanks!

You have two choices. You can do it the JavaScript way with a string, like:
div(id=attendanceAnalytics.uid, class='googleChartContainer-' + attendanceAnalytics.uid)
or you create an JavaScript object containing keys and values to use them with the typical jade attribute div&attribute(object), like this:
- var attr = {"id": attendanceAnalytics.uid, "class": 'googleChartContainer-' + attendanceAnalytics.uid}
div&attribute(attr)
Take a look into the JadeLang Docs, chapter attributes.

Related

populate object properties using lambda expression in typescript

Newbie Alert! I feel silly asking this question but I need someone to teach me the correct syntax.
I have code that looks like this:
let thing: INewThing;
thing.personId = another.personId;
thing.address = another.work.address;
thing.greades = another.subjectInfo.grades;
thing.isCurrent = another.student.isCurrent;
I know it can be written cleaner. I want to use a lamda expression, something like this:
let thing: INewThing => {
personId = another.personId,
address = another.work.address,
grades = another.subjectInfo.grades,
isCurrent = another.student.isCurrent
} as IThingUpdate;
I have looked and looked for an example. I have yet to find one that works for me. It's just syntax but no matter what I try it doesn't work.
You're just looking to create a new object, which is a pretty different thing from a "lambda" (function). Just declare the object. You don't need a function.
const thing = {
personId: another.personId,
address: another.work.address,
// use the correct spelling below - no 'greades'
grades: another.subjectInfo.grades,
isCurrent: another.student.isCurrent,
};
If the another is typed properly, that should be sufficient.
If the another object had more properties using the same path, another option would be to destructure those properties out, then declare the object with shorthand, eg:
const originalObj = { prop: 'val', nested: { foo: 'foo', bar: 'bar', unwanted: 'unwanted' } };
const { foo, bar } = originalObj.nested;
const thing = { foo, bar };
Destructuring like this, without putting the values into differently-named properties, helps reduce typos - if a property starts out, for example, as someLongPropertyName, putting it into a standalone identifier someLongPropertyName and then constructing an object with shorthand syntax ensures that the new object also has the exact property name someLongPropertyName (and not, for example, someLongPRopertyName - which isn't that uncommon of a mistake when using the more traditional object declaration format).
But since all the paths in your another object are different, this approach wouldn't work well in this particular situation.

use nodejs var as json object statement?

how do I use a nodejs var inside a json statement, I dont realy have the required vocabulary to explain but here is my simplifyed code:
test.json:
{
"test1":["test1.1", "test1.2"],
"test2":["test2.1", "test2.2"]
}
test.js:
const json = require("./test.json")
function myFunction(TYPE){
return(json.TYPE[0])
}
console.log(myFunction("test1"))
as I use the "type" var it tries to uses it as an json statement or object but obviously there is no "type" there only is "test1" and "test2" but it interprets as "type" instead
Brackets to access the variable key should work
function myFunction(TYPE){
return(json[TYPE][0])
}
In JavaScript, json objects are pretty much same as plain JS objects. You need to use string as an index to access properties:
// This could be your json file, its almost the same
// Just require it like you did instead of using const JSON like i am
const json = {
"test1":["test1.1", "test1.2"],
"test2":["test2.1", "test2.2"]
}
function myFunction(TYPE){
// Access the json by using keyword directly as index string
return(json[TYPE])
// because TYPE is a string, TYPE[0] would mean first letter of TYPE string
}
function myFunctionDeeper(TYPE){
// To access a field and array in that field
return(json[TYPE][0])
}
console.log(myFunction("test1"))
console.log(myFunctionDeeper("test1"))
// example for what happens when accessing string by index
console.log("test1"[0])
Read more about objects here

Twig function/filter with no input?

I'm using Slim 3 and Slim Twig-View. I want to add a Twig function (or filter, not sure what is the difference?) which generates a random string, and doesn't take any input.
I was able to add a filter like this:
$twig->getEnvironment()->addFilter(
new \Twig_Filter('guid', function(){ return generateGUID(); })
);
But I can't seem to use it without providing some dummy input:
{{ 0|guid }} This will work
{{ guid }} This will not work
How can I use my guid filter/function without providing any input?
A filter always apply on something, it filters something.
What you want is a function, indeed.
The extending Twig page of the documentation is an incredible source of information on that matter.
At first glance, I would even have said you should define a tag for this but the documentation on the tag, explicitly says:
If your tag generates some output, use a function instead.
Source: https://twig.symfony.com/doc/3.x/advanced.html#tags
So indeed, in order to define a function:
Functions are defined in the exact same way as filters, but you need to create an instance of \Twig\TwigFunction:
$twig = new \Twig\Environment($loader);
$function = new \Twig\Twig_Function('function_name', function () {
// ...
});
$twig->addFunction($function);
So more specifically for you:
$container->get('view')->getEnvironment()->addFunction(
new Twig_SimpleFunction('guid', function(){ return generateGUID(); })
);
Will be accessible via:
{{ guid() }}
Other worth reading:
extending twig, in Slim documentation
you can achieve the same with a macro

node ejs reference error data not defined at eval when handing data to view

i've been closing in on a node application using express and ejs, but when i try to hand data to my view from the controller like so
var myData = {
theData: data
};
res.render(path.join(__dirname + '/../views/index'), myData);
i get a nice error
ReferenceError:.. myData is not defined eval (from ejs lib)
when trying to access myData in the view like so
var data = <%-myData%>;
or in any other way basically, i've tried stringifying the data, wrapping it in another object and stuff like that but it still just won't show up, i have the feeling i'm missing something really basic here, does anyone have an idea on how to fix this?
The second argument you pass to render() is an object containing the view variables you want to use in your template. So the error you are seeing makes sense. If you want to use myData in that way you'd have to do something like this in your controller/app:
res.render(..., { myData: JSON.stringify(myData) });
There's a silly mistake I make when I try to send data from the server.
Here's the mistake:
var data = <%=myData%>;
What you should do when passing it:
var data = <%-myData%>;
It's supposed to be a dash NOT an equal before the variable name.
If your are generating the template with the HtmlWebpackPlugin plugin, the data should be passed in your webpack configuration file, along with the templateParameters property.
For example:
...
plugins: [
new HtmlWebpackPlugin({
filename: __dirname + "/src/views/index.ejs",
template: "./src/views/index_template.ejs",
templateParameters: {
myData,
},
}),
],
...

Can I add attributes to a Backbone View?

I have been working with backbone for a while and I am now using a number of views. In some of my views I sometimes add custom attributes like:
var DataGrid = Backbone.View.extend({
className:"datagrid",
lookup: {
header: "", //Header wrapper row element
headers: [], //Views in header
body: "", //Body wrapper row element
rows: [] //Views in body
},
events: {
...
},
initialize: function() {
...
},
render: function() {
...
}
});
As you can see I have "lookup" as an extra attribute to the Object. I use DataGrid in a number of my views and I am experiencing a very strange behaviour. When I switch between views that use DataGrid, "lookup" would still be populated with the old data. I use "new" when creating a new DataGrid but I still find old data. Am I missing something?
EDIT: Following #rabs reply. I did a search on static variables in Backbone and found this: Simplify using static class properties in Backbone.js with Coffeescript
I know an answer has been accepted on this (a while ago), but as I came across this question while working on a backbone project recently, I thought it would be worth mentioning that you can define attributes as a function also. This is especially useful for views that need to have attributes set to values in their current models.
By defining attributes as a function you can do something like
var myObject = Backbone.View.extends({
attributes: function() {
if(this.model) {
return {
value: this.model.get('age')
}
}
return {}
}
});
Hope that helps someone
Declaring variables in this way the scope of the variable is to the class not the instance, similar to s static or class variable.
So yeah the lookup object will shared between your different instances.
You could pass the lookup object in to your instance when you create it that way it will behave as an instance variable.

Resources