I am trying to write a mixin in Jade. I would like to pass a parameter through mixin to build same type of block with different value at different states. In the mixin I want to write a conditional that checks if passed parameter is equal to some value. But unfortunately it is not working and I can't find proper documentation anywhere. My code section is following:
mixin test(id)
if territoryList
each val in territoryList
- if (val.parentArea==id){
button.btn.btn-primary.btn-block=val.name
- }
And I am calling it like test('1')
What is the problem?
I don't think your if is supposed to be a javascript if.
Don't you want this ?
mixin test(id)
if territoryList
each val in territoryList
if val.parentArea==id
button.btn.btn-primary.btn-block= val.name
Related
Sorry to all you Groovy dudes if this is a bit of a noob question.
In SOAPUI, i can create a Groovy script where i can define an arbitrary variable to the run context to retrieve at a later time.
context.previouslyUndefinedVariable = 3
def num = context.previouslyUndefinedVariable
What feature of Groovy allows previously undefined variables to be added to an object like this? I would like to learn more about it.
Many thanks in advance!
Groovy has the ability to dynamically add methods to a class through metaprogramming.
To learn more, see:
What is Groovy's MetaClass used for?
Groovy Goodness: Add Methods Dynamically to Classes with ExpandoMetaClass
Runtime and compile-time metaprogramming
The accepted answer is a bit of a poor explanation for how SoapUI is doing it.
In this case, context is always an instance of some SoapUI library java class (such as WsdlTestRunContext), and these are all implementations of Map. You can check context.getClass() and assert context in Map.
When you look up a property on a Map, Groovy uses the getAt and putAt methods. There are various syntaxes you can use. All of these are equivalent:
context.someUndef
context.'someUndef'
context[someUndef]
context['someUndef']
context.getAt('someUndef')
And
context.someUndef = 3
context.'someUndef' = 3
context[someUndef] = 3
context['someUndef'] = 3
context.putAt('someUndef', 3)
I like to use any of the above that include quote marks, so that Groovy-Eclipse doesn't flag it as a missing property.
It's also interesting that Groovy looks for a getAt() method before it checks for a get method being referred to as a property.
For example, consider evaluating "foo".class. The String instance doesn't have a property called class and it also doesn't have a method getAt(String), so the next thing it tries is to look for a "get" method with that name, i.e. getClass(), which it finds, and we get our result: String.
But with a map, ['class':'bar'].class refers to the method call getAt('class') first, which will be 'bar'. If we want to know what type of Map it is, we have to be more specific and write in full: ['class':'bar'].getClass() which will be LinkedHashMap.
We still have to specify getClass() even if that Map doesn't have a matching key, because ['foo':'bar'].class will still mean ['foo':'bar'].getAt('class'), which will be null.
I'm trying to understand twigs attribute() function, because it seems to me that this
attribute(object, parameter)
and this
object[ parameter ]
Would do the same thing. They return the value of that parameter in the object. I realize that brackets can also be used to get a value from an array with an index, but if the parameter is a string it seems to get the value from the parameter just as well. What else does attribute() do that Im missing?
The attribute function can also be used to call methods of objects and enables you to pass arguments towards it
{{ attribute(object, method, arguments) }}
I am trying to understand the following code snippet following site.
<% refChanges.getCommits(repository).each { commit -> %>
- ${commit.author.name} | ${commit.displayId} | ${commit.message} | ${commit.authorTimestamp}
<% } %>
The script is using a getCommits method, but when I look at the documentation for the RefChange interface I do not see any such method.
I consider myself an expert Java developer, but I have no workable knowledge in Groovy, so I assume that I am misunderstanding Groovy or the BitBucket documentation (or both).
In Groovy it's possible to add methods to a class or interface at run-time via meta-programming. Since the RefChange interface does not include getCommits(), it must be that the method is being added after-the-fact. Based on their example code, it looks like they're using the meta-class.
Where is getCommits()?
For example, in Groovy the Collection interface gets the method findAll() (along with many other methods). I can confirm this as follows:
assert Collection.metaClass.metaMethods*.name.contains('findAll') == true
The code above grabs the names of all the meta methods and then uses contains() to see if a match is found. You can confirm the same for getCommits() in a similar way:
assert Collection.metaClass.metaMethods*.name.contains('getCommits') == true
Note that I specified Collection rather than RefChange because refChanges is a Collection of RefChange. And so I think Atlasssian stuck getCommits() into Collection as a convenience method.
How does it work?
To understand what's going, I'll remove the templating code:
refChanges.getCommits(repository).each { commit ->
"${commit.author.name} | ${commit.displayId} | ${commit.message} | ${commit.authorTimestamp}"
}
getCommits() returns a Collection of com.atlassian.bitbucket.commit.Commit.
Object.each(Closure) is added by the Groovy GDK (yes, into the Object class) and it calls the Closure repeatedly; each time with an element of the Collection.
Although it's not apparent in the example code, the line within the each(Closure) is a GString. Basically the expressions within the ${...} are evaluated and the whole thing is concatenated into a String.
I'm trying to pass an object from jade to ng-init in angular
This: doesn't work:
ng-init='tables=!{JSON.stringify(tables)}'
This: expands but,
ng-init='tables=#{JSON.stringify(tables)}'
the output is unescaped and filled with "s
ng-init="tables={"12":{"id":....
and the view isn't updated in either of the cases. This article implies that first one should work, but like I said, it doesn't even expand,
ng-init='tables=!{JSON.stringify(tables)}'
in source code shows up exactly the same in the HTML source
ng-init='tables=!{JSON.stringify(tables)}'
Actually, the #{...} approach seems to work fine.
It is probably the way console.log prints attributes' values that confused you.
ng-init="tables=#{JSON.stringify(tables)}"
Take a look at this short demo.
In what use-case you want to pass data directly from Jade to angular? I think you could to this job in controller like this :
$scope.init = function () {
// init stuff
}
...and in your view :
ng-init = init()
I'm not even sure about how to title this qn. But, hope there is an easy way to do it in dynamic language like groovy.
say I have a class Service, where I delegate the business logic. the methods in it are
funA(), funB()... funX().
Now I have a controller class, where I call the service closure, which can be invoked like service.funA() . Now based on a variable (which can have values A, B ... X), I need to cal the correct service closure. Basically to avoid writing lot of if conditional statements. Something like service."fun+var"() would do. I'm not sure whether it is possible to substitute variable in closure (function)name. or any way by passing function (name) as a parameter...not sure
I think PHP has a similar feature http://php.net/manual/en/functions.variable-functions.php
thanks for any pointer..
Yes, this is possible. This should do what you want:
service."fun${var}"()
The correct title is dynamic method invocation.