Knockout Binding with Multiple If statements - web

I am applying binding on a style and have succeeded in making the background colour change based on two scenarios. At present it says if the status is 'START', make the background #d10000, else make the background #93d667.
style: { background: ManagerStatus() == 'START' ? '#d10000' : '#93d667' }
I would like the following functionality:
If START, make #d10000
else if CONTINUE, make #93d667
else make #f7f7f7
How do I achieve these multiple case statements in Knockout binding?
Regards
Alexandra

Thanks guys. For future reference someone showed me that you can actually have multiple cases in the data-bind attribute:
{background: ManagerStatus() == 'START' ? '#d100000' : (ManagerStatus() == 'CONTINUE' ? '#93d667' : '#f7f7f7')}
Alexandra

You avoid filling your html with conditional logic and create a knockout computed observable in your viewmodel like so:
// or however your viewModel is currently set up.
var viewModel = {
ManagerStatus: ko.observable()
}
viewModel.statusBackground = ko.computed(function() {
status = this.ManagerStatus(),
switch (status) {
case "START": return "#d10000";
case "CONTINUE": return "#93d667";
default: return #f7f7f7;
}
}, viewModel);
html
style: { background: statusBackground }

You could do it by nesting two ternary operator expressions. But doing so it's not a good idea: it's much better to modify your View Model, and include a computed observable that returns the backgraound color. Something like this:
var vm = function() {
var self = this;
self.ManagerStatus = ko.observable();
self.backgroundcolor = ko.computed(function() {
ManagerStatus() == 'START'
? '#d10000' : ManagerStatus() == 'CONTINUE'
? '#93d667' : '#f7f7f7';
});
return self;
};
The binding would be like this:
style: { background: backgroundcolor }
Note that you in this case can use a pure computed, instead of a regular computed.
NOTE: I've shown how to write a nested ternary operator, and you could include it in the binding expression. But, if it looks ugly in a view model definition, it's even more ugly in a binding expression. In fact, I wouldn't write it like this in the view model definition. Much better to use chained if else or switch to make it more readable.

Related

Check equaling enum without parameter

I use enums but can't find good way to check eqauling.
enum Turn {
A(value:Int);
B(value:Int);
}
class Test {
static function main() {
var turn = Turn.A(100);
//I want to Check turn is Turn.A(any value) without using 'switch'.
if (turn == Turn.A) ...
}
}
Is there any good and simple way to checking?
You can use the .match() function:
if (turn.match(Turn.A(_)))
I haven't tested this, but it might be faster using Type class:
if (Type.enumConstructor(turn) == "A") ...
Because it is unsafe ("A" could be a typo), I suggest to use ExprTools:
import haxe.macro.ExprTools.*;
if (Type.enumConstructor(turn) == toString(macro A)) ...
There is another way, but I don't think it is faster :
if (Type.enumIndex(turn) == Type.enumIndex(A(0))) ...
And you might get condition evaluated to true for different enums:
enum Color { Red; }
if (Type.enumIndex(turn) == Type.enumIndex(Red)) ... // true

How do I make puppeteer wait for element to load (in a loop)?

I am trying to use puppeteer in order to fill in a form and get the results.
when the form is submitted correctly, a table containing the results appear which has #some_id. Now I'm looking for a good way to wait until the table is loaded and if the code fails, redo the process of filling in the form until it works correctly. I want it to do something like this (pseudo code):
while(table_is_not_loaded){
get_information;
fill_in_the_form;
submit_the_form;
}
I think that it's maybe achievable using page.waitForSelector() function, but I can't use it the way I want and I also don't know how it handle errors if the selector is not ready or visible.
You could do something like this:
let table_is_loaded = true;
await page.waitForSelector('someID').catch(e => table_is_loaded = false);
while(!table_is_loaded){
get_information;
fill_in_the_form;
submit_the_form;
table_is_loaded = true;
await page.waitForSelector('someID').catch(e => table_is_loaded = false);
}
Maybe something like:
while(true){
try {
await page.waitForSelector('#foo')
get_information;
fill_in_the_form;
submit_the_form;
break
} catch(e) {
}
}
after some searching and trying different pieces of code , i came to a solution and it was using the.$eval() method to access html attributes and checking the height of the element( you could also check other things as well like display or visibility )
const isNotHidden = await mainPage.$eval(
"#some_id",
elem => {
return (
window.getComputedStyle(elem).getPropertyValue("height") >= "5px"
);
}
);
link to main answer that helped me achieve this : https://stackoverflow.com/a/47713155/11968594

Using multiple Filters in Query

Is there a way to add multiple filters to a query based on a condition to the Query Expression.
For eg something along the lines of.
AddressFluentHelper queryHelper=service.getAllAddress;
if(zipCode!=null){
queryHelper.filter(Address.ZIPCODE.eq(zipCode))
}
if(street!=null){
queryHelper.filter(Address.STREET.eq(street))
}
If this is allowed is the default condition 'AND' between the different filters?
If the default is 'AND' how do we achieve the use case of 'OR'
The default behavior is an 'AND' connection between all given FilterExpression.
To make this more explicit as well as allowing an 'OR' connection you might consider building the FilterExpression "externally", e.g. like this:
import io.vavr.collection.List;
...
List<ExpressionFluentHelper<YOUR_ENTITY>> expressions = List.empty();
if (zipCode != null) {
expressions = expressions.append(Address.ZIPCODE.eq(zipCode););
}
if (street != null) {
expressions = expressions.append(Address.STREET.eq(street));
}
AddressFluentHelper queryHelper = service.getAllAddress();
if (!expressions.isEmpty()) {
// this combines all elements in the "expressions" via "or", starting from the left/the first entry
ExpressionFluentHelper<YOUR_ENTITY> combinedExpression = expressions.reduceLeft(ExpressionFluentHelper::or);
queryHelper.filter(combinedExpression);
}

drupal menu hook -- how to add formatting

I want to add some additional formatting to my menu. I've been looking at menu.inc and am unsure which method would i override to do something like the following.
if content type = "fund"
print " some additional formatting "
That's not really something you would want to do in the hook_menu, actually.
I'm not sure what you're doing for sure, but it sounds like what you want to do is to use the hook_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) hook, something like this:
function example_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if ($op == 'view' && $node->type == 'fund') {
$node->content['my_fund_data'] = array(
'#value' => 'Some additional formatting',
'#weight' => 10,
);
}
}
Now, if what you want to do is change the content instead of just add something below it, you'll want to investigate what the rendered node looks like - I suggest installing the devel module, which will give you a link to view the rendered node data easily.

How does one return from a groovy closure and stop its execution?

I would like to return from a closure, like one would if using a break statement in a loop.
For example:
largeListOfElements.each{ element->
if(element == specificElement){
// do some work
return // but this will only leave this iteration and start the next
}
}
In the above if statement I would like to stop iterating through the list and leave the closure to avoid unnecessary iterations.
I've seen a solution where an exception is thrown within the closure and caught outside, but I'm not too fond of that solution.
Are there any solutions to this, other than changing the code to avoid this kind of algorithm?
I think you want to use find instead of each (at least for the specified example). Closures don't directly support break.
Under the covers, groovy doesn't actually use a closure either for find, it uses a for loop.
Alternatively, you could write your own enhanced version of find/each iterator that takes a conditional test closure, and another closure to call if a match is found, having it break if a match is met.
Here's an example:
Object.metaClass.eachBreak = { ifClosure, workClosure ->
for (Iterator iter = delegate.iterator(); iter.hasNext();) {
def value = iter.next()
if (ifClosure.call(value)) {
workClosure.call(value)
break
}
}
}
def a = ["foo", "bar", "baz", "qux"]
a.eachBreak( { it.startsWith("b") } ) {
println "working on $it"
}
// prints "working on bar"
I think you're working on the wrong level of abstraction. The .each block does exactly what it says: it executes the closure once for each element. What you probably want instead is to use List.indexOf to find the right specificElement, and then do the work you need to do on it.
If you want to process all elements until a specific one was found you could also do something like this:
largeListOfElements.find { element ->
// do some work
element == specificElement
}
Although you can use this with any kind of "break condition".
I just used this to process the first n elements of a collection by returning
counter++ >= n
at the end of the closure.
As I understand groovy, the way to shortcut these kinds of loops would be to throw a user-defined exception. I don't know what the syntax would be (not a grrovy programmer), but groovy runs on the JVM so it would be something something like:
class ThisOne extends Exception {Object foo; ThisOne(Object foo) {this.foo=foo;}}
try { x.each{ if(it.isOk()) throw new ThisOne(it); false} }
catch(ThisOne x) { print x.foo + " is ok"; }
After paulmurray's answer I wasn't sure myself what would happen with an Exception thrown from within a closure, so I whipped up a JUnit Test Case that is easy to think about:
class TestCaseForThrowingExceptionFromInsideClosure {
#Test
void testEearlyReturnViaException() {
try {
[ 'a', 'b', 'c', 'd' ].each {
System.out.println(it)
if (it == 'c') {
throw new Exception("Found c")
}
}
}
catch (Exception exe) {
System.out.println(exe.message)
}
}
}
The output of the above is:
a
b
c
Found c
But remember that "one should NOT use Exceptions for flow control", see in particular this Stack Overflow question: Why not use exceptions as regular flow of control?
So the above solution is less than ideal in any case. Just use:
class TestCaseForThrowingExceptionFromInsideClosure {
#Test
void testEarlyReturnViaFind() {
def curSolution
[ 'a', 'b', 'c', 'd' ].find {
System.out.println(it)
curSolution = it
return (it == 'c') // if true is returned, find() stops
}
System.out.println("Found ${curSolution}")
}
}
The output of the above is also:
a
b
c
Found c
Today I faced a similar problem while working with each closure. I wanted to break the flow of execution based on my condition but couldn't do it.
The easiest way to do in groovy is to use any() on a list instead of each if you wish to return a boolean based on some condition.
Good ole for loop still works in Groovy for your use case
for (element in largeListOfElements) {
if(element == specificElement){
// do some work
return
}
}

Resources