binding.scala component to string conversion - scala.js

I have a binding.scala component and a third party scalajs library that takes html string as input. How can the b.s component can be passed to the library method as an argument?
Specifics:
import com.thoughtworks.binding.Binding._
import com.thoughtworks.binding.{Binding, dom}
#dom def renderComponent: Binding[Element] = <h1> I am a component </h1>
def thirdPartyFunction(str: String) = {
...
}
I would like to call the function like thirdPartyFunction(renderComponent.bind.outerHtml.toString).
However that call never gets executed.
I think this is related to some basic understanding with B.S up until now I have not faced with. Any suggestions?

The answer is to wrap the .bind call with watch. For instance, in the window.onload function, something similar to the following:
window.onload = _ => Binding{
thirdPartyFunction(renderComponent.bind.outerHtml.toString)
}.watch()
Note that it is possible to initialize components without functions like window.onload. See this question How to execute some init after element loaded to dom with Binding.scala

Related

Customized Iterator for the Process.repeatEval in scalaz stream

I want to parse infinite urls by using scalaz stream. The template url response looks like this :
{
nextUrl: "nextUrl"
}
I am thinking to use scalaz Stream to parse infinitely. The method I am gonna to use is Process.repeatEval. However, it is little bit hard to do it since the next link is embedded inside the current url. Thus, I create a customized iterator and here is some pseudo code
class Iterator {
var currentUrl = null //state...
def hasNext(): Boolean
def next(): UrlContent
}
Process.repeatEval(Task {iterator}).takeWhile(_.hasNext()).map(_.next()).run.run
It is working, but I am not a fun of this, because iterator has state, and I am trying to remove the usage of mutable value.
Back to my question, am I looking for the suitable choice (Process.repeatEval) from scalaz stream. If yes, should I use this customized iterator.
Many thanks in advance

How to invoke 3rd party javascript from scala-js?

I need help initializing a native JS var from within a scalajs app (specifically a scalajs-react app). Fundamentally, I'm trying to use Bootstrap Responsive data-tables and I need to initialize a data table by getting the element of the data table in my HTML via a call to dom.getElementById which will be of type DataTable and then I need to initialize like this:
$(document).ready(function() {
$('#example').DataTable();
} );
I've been staring at the #js.native stuff and can't quite figure out how to make the connection to that native JS. Any help would be greatly appreciated. For reference, the link to the native javascript of the responsive data-table is here. An additional question for those with a scalajs-react background (are you there #japgolly?) is whether or not the best place to make this data-table initialization invocation should be in the ReactComponentB.componentDidMount() method?
The simplest way to set up the data table is by doing so using the dynamic API:
dom.document.getElementById("example").asInstanceOf[js.Dynamic].DataTable()
Of course you need to do so only once the document is loaded. You can use scala-js-jquery to do so:
jQuery(dom.document).ready(() =>
dom.document.getElementById("example").asInstanceOf[js.Dynamic].DataTable()
)
If you would like to have a nicer (and typesafe) invocation of DataTable, you can follow the Monkey Patching Guide (sorry no anchor, search for the term):
#js.native
trait DataTableElement extends dom.Element {
def DataTable(): Unit = js.native
}
object DataTableElement {
implicit def element2dataTableElement(e: dom.Element): DataTableElement =
{
e.asInstanceOf[DataTableElement]
}
}
You now won't need the cast anymore:
dom.document.getElementById("example").DataTable()
And:
jQuery(dom.document).ready(() =>
dom.document.getElementById("example").DataTable()
)

playframework with Twirl views not found: value

i pass a lot of time trying to solve very simple problem render à string or(List) from controller to view using playframework java and Twirl, my code here
in my controller
public Result list(){
//List<String> todo = Arrays.asList("sup1","sup2","sup3");
String nana = "coco";
return ok(index.render(nana));
}
in my view
#(message: String)
#(nana:String)
#main("Welcome to Play") {
#play20.welcome(message, style = "Java")
<h1>#nana</h1>
}
so there are the some configuration for Twirl or automatically ? anyone help me to render data to view and thanks
What is the error you're seeing? What are the full blocks of code, with all imports?
The syntax seems to be all wrong:
Your template should only have one parameter declaration, which is the #(...) line at the top. If you want to pass in two values, you should write #(message: String, nana: String) at the top of your template. And then you need to pass values for both in when you call index.render(message, nana).
I'm not sure what #main refers to, since imports aren't listed, but you should try getting it to work first without that block. Render a plain string, then add in some variables, then maybe try for a fancy callback like #main.

What is the purpose of passing "globals()" as web.py fvars?

web.application accepts an undocumented fvars argument to which the web.py tutorial passes globals() like so:
import web
class index:
def GET(self):
return "Hello, world!"
urls = (
'/', 'index'
)
if __name__ == "__main__":
app = web.application(urls, globals())
I've seen at least one application that passes locals(). What is this variable used for, and why would you want to pass it locals() or globals()?
It's used by application.handle() (which in turn calls application._delegate()) to convert the handler class from a string to the class object itself. Source code here.
For example, in your code snippet above, urls = ('/', 'index') is the URL-to-class-string mapping. So web.application needs your globals() dict to be able to look up the string 'index' and get the class itself.
I actually think this is a somewhat non-Pythonic design. Why not just pass in the class directly? I think web.py supports that approach too. However, I believe the classes were done as strings so autoreload is simpler. The autoreload code uses fvars heavily.
Re locals(): at the module level, locals() doesn't really make sense, but it returns the same dictionary as globals(), which is why that would work.

Not able to use Mockito ArgumentMatchers in Scala

I am using ScalaMock and Mockito
I have this simple code
class MyLibrary {
def doFoo(id: Long, request: Request) = {
println("came inside real implementation")
Response(id, request.name)
}
}
case class Request(name: String)
case class Response(id: Long, name: String)
I can easily mock it using this code
val lib = new MyLibrary()
val mock = spy(lib)
when(mock.doFoo(1, Request("bar"))).thenReturn(Response(10, "mock"))
val response = mock.doFoo(1, Request("bar"))
response.name should equal("mock")
But If I change my code to
val lib = new MyLibrary()
val mock = spy(lib)
when(mock.doFoo(anyLong(), any[Request])).thenReturn(Response(10, "mock"))
val response = mock.doFoo(1, Request("bar"))
response.name should equal("mock")
I see that it goes inside the real implementation and gets a null pointer exception.
I am pretty sure it goes inside the real implementation without matchers too, the difference is that it just doesn't crash in that case (any ends up passing null into the call).
When you write when(mock.doFoo(...)), the compiler has to call mock.doFoo to compute the parameter that is passed to when.
Doing this with mock works, because all implementations are stubbed out, but spy wraps around the actual object, so, the implementations are all real too.
Spies are frowned upon in mockito world, and are considered code smell.
If you find yourself having to mock out some functionality of your class while keeping the rest of it, it is almost surely the case when you should just split it into two separate classes. Then you'd be able to just mock the whole "underlying" object entirely, and have no need to spy on things.
If you are still set on using spies for some reason, doReturn would be the workaround, as the other answer suggests. You should not pass null as the vararg parameter though, it changes the semantics of the call. Something like this should work:
doReturn(Response(10, "mock"), Array.empty:_*).when(mock).doFoo(any(), any())
But, I'll stress it once again: this is just a work around. The correct solution is to use mock instead of spy to begin with.
Try this
doReturn(Response(10, "mock"), null.asInstanceOf[Array[Object]]: _*).when(mock.doFoo(anyLong(), any[Request]))