ScalaJs With Play Framework (Error in Tests) - scala

I am trying to use ScalaJs cross build project with Play Framework 2.5.
I am facing a problem when I am trying to run the tests for Client.scala .
The error I am getting is -
caused by: TypeError: Cannot call method "appendChild" of null .
Client snippet
#JSExport
object DashboardClient extends js.JSApp {
#JSExport
def main(): Unit = {
val dashboard = new Dashboard
dom.document.getElementById("bodyContent").appendChild(dashboard.bodyFrag.render)
}
This bodyFrag is inside a different class
def bodyFrag =
div(
div(
`class` := "row border-bottom",
div(
`class` := "col-md-12",
div(
`class` := "col-md-2 image-alignment",
img(width := "161", src := "/assets/images/mountain.jpg")
),
div(`class` := "col-md-10")
)
),
div(
`class` := "row border-bottom",
div(
`class` := "col-md-12",
div(
`class` := "col-md-12",
h1(`class` := "text-center", "Dashboard")
)
)
)
)
So when I am trying to test is using utest I get the above mentioned error.
Please help.
P.S - I am completely new to Scala and ScalaJs.

Well, the error doesn't appear to have anything to do with bodyFrag. (Or Play, or even Scala.js, really.) The error is literally saying that getElementById("bodyContent") is null, which means it doesn't yet exist. I assume it's declared in the HTML.
This is a common trap in browser code. You need to wait for the DOM to be ready before you try manipulating it; you don't show the HTML page, so I'm not sure whether you're doing that, but I suspect not.
There are various ways to wait for DOM ready -- the common (but slower) onload approach, and the jQuery approach, are discussed in the jQuery documentation. As a quick fix, I would recommend wrapping the call to your Scala.js code inside window.onload.

Related

Play Framework 2.4.0 and I18n with Scala

I have a project with Play Framework 2.3.8 and I'm migrating in Play Framework 2.4 but I have a problem with I18n.
Now I have in a view code like this:
#Messages("components.navbar.text")(locale.MyLang)
where locale is:
object locale {
var MyLang =Lang("it")
def changeLang(newLang:String): Unit ={
MyLang=Lang(newLang)
}
}
I would mantainer this structure without using implicit lang, is possible ?
I have some situation where I use in the same page different language and in this case is difficult and boring with the implicit lang.
If I understand your question correctly, which is that you want to override the user's chosen language for certain blocks of the page, I would do this (for Play 2.4) using an implicit Messages object:
#()(implicit messages: Messages)
<!-- some section in the user's chosen language -->
<h1>#Messages("hello.world")</h1>
<!-- some section in a specific language -->
#defining(messages.copy(lang = play.api.i18n.Lang("it")) { implicit messages =>
<h2>#Messages("something.in.italian")</h2>
}
That is, use defining to create a new (implicit) messages for certain nested blocks of HTML.
If you really wanted to go to town (and I wouldn't necessarily recommend this) you could add an italian method to Messages via an implicit class:
(in my.package.utils.i18n.MessagesExtensions.scala):
package my.packages.utils.i18n
import play.api.i18n.{Lang, Messages}
implicit class MessagesExtensions(messages: Messages) {
def italian = messages.copy(lang = Lang("it"))
// and an `as` method for good measure:
def as(code: String) = messages.copy(lang = Lang(code))
}
To have that work in a view you need to add the class to your templateImport in your build.sbt:
templateImports in Compile ++= Seq(
"my.packages.utils.i18n.MessagesExtensions"
)
Then in your templates you can just to this:
#()(implicit messages: Messages)
<!-- some section in the user's chosen language -->
<h1>#Messages("hello.world")</h1>
<!-- some section in a specific language -->
#defining(messages.italian) { implicit messages =>
<h2>#Messages("something.in.italian")</h2>
....
}
<!-- or singly, in another language -->
<h3>#Messages("another.thing.in.french")(messages.as("fr"))</h3>
But that might be overkill, unless it really saves you a lot of boilerplate language switching.

Delphi: How to allow setting a TClass-property of a TCollectionItem at design time

I'm developing a component that works on several classes.
In order to allow adding the list of managed classes, I've written a TCollection's inherited class in which each item (inherited from TCollectionItem) defines a published "TargetClassName" property.
The "TargetClassName" property's setter function, calls the following function in order to find the corrisponding TClass:
function FindAnyClass(const Name: string): TClass;
var
ctx: TRttiContext;
typ: TRttiType;
list: TArray<TRttiType>;
begin
Result := nil;
ctx := TRttiContext.Create;
list := ctx.GetTypes;
for typ in list do
begin
if typ.IsInstance and (EndsText(Name, typ.Name)) then
begin
Result := typ.AsInstance.MetaClassType;
break;
end;
end;
ctx.Free;
end;
(Thanks to Dalija Prasnikar for writing the function Get class by its name in Delphi).
Now, I'm wondering if there's a better way to allow adding classes to a TCollectionItem at design time.. What do you think about it?
Hope to read interesting solutions!
Thanks to all.
in creation on TCollection You need To introduce Collation Class
it's Posible in two way
1 : hard coded in create time X := TMycollation.Create(TMyCollationClass)
2 : your solution X := TMycollation.Create(FindAnyClass('TMyCollationClass'));

Dynamically evaluating code at runtime

Is it possible to take a string/AST of source code and evaluate it (like eval()) at runtime in Fantom? I found some suggesting features in the documentation but not obvious evidence.
It's not as easy as calling an eval() function, but it is possible. You need to first compile your Fantom code into a class before you can execute it.
Plastic, a library from Alien-Factory, does just that. Example:
using afPlastic
class Example {
Void main() {
eval("2 + 2") // --> 4
}
Obj? eval(Str code) {
model := PlasticClassModel("MyClass", true)
model.addMethod(Obj?#, "eval", "", code)
myType := PlasticCompiler().compileModel(model.toFantomCode)
return myType.make->eval()
}
}
The PlasticCompiler class does the job of compiling Fantom code into a usable Type.
It uses the Fantom compiler library and is based on code found in Fansh - a Fantom shell, part of the Fantom distribution.

capture spaced user input

I am trying to capture user input in Go with little luck. I can get non-spaced words to work:
var s string
println("enter string:")
fmt.Scan(&s)
However, the Go documentation says that scan will delimit at spaces and new lines. So I think I have to set up bufio.Reader's ReadLine. Here is my attempt, which will not compile:
package main
import (
"bufio"
"os"
"fmt"
)
const delim = '\n'
const file = "file"
func main() {
r := bufio.NewReader() *Reader
println("enter string:")
line, err := r.ReadString(delim)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(line)
}
errors:
1.go:14: not enough arguments in call to bufio.NewReader
1.go:14: undefined: Reader
So, how do I define "Reader"? And if it was defined, would this be the correct way to capture the input as a string, delimited at "\n", and not at the space? Or should I be doing something completely different?
Thanks in advance.
Change
r := bufio.NewReader() *Reader
to read
r := bufio.NewReader(os.Stdin)
to fix the problem.
The original encantation is incorrect because you seem to just copied and pasted the method's signature from the spec, but the spec defines the signature, not an example of a call, so *Reader in there is the method's return type (the type your variable r will have). And the method's sole argument is defined to be rd io.Reader; that interface is conveniently implemented by the os.Stdin symbol which seems like a perfect match for your task.
P.S.
Consider reading all the docs in the "Learning Go" documentation section, especially "Effective Go".
If you look at the documentation for bufio.NewReader, it takes an argument of type io.Reader (which makes sense, because it takes a normal reader and makes it buffered, similar to java.io.BufferedReader in Java, which also takes a Reader argument). What is io.Reader? Looking at its documentation, it is an interface, specifying anything that has a Read method. Many types have a Read method; most commonly, *os.File. So you can construct a File using os.Open etc.
f, _ := os.Open(file)
r := bufio.NewReader(f)

Scala problem with jMock expectations and returning a value from mock

Solved. IntelliJ didn't highlight the fact that my imports were incomplete.
Hi,
I have a simple Scala program that I'm trying to develop using jMock. Setting basic expectations works nicely but for some reason Scala does not understand my attempt to return a value from a mock object. My maven build spews out the following error
TestLocalCollector.scala:45: error: not found: value returnValue
one (nodeCtx).getParameter("FilenameRegex"); will( returnValue(regex))
^
And the respective code snippets are
#Before def setUp() : Unit = { nodeCtx = context.mock(classOf[NodeContext]) }
...
// the value to be returned
val regex = ".*\\.data"
...
// setting the expectations
one (nodeCtx).getParameter("FilenameRegex"); will( returnValue(regex))
To me it sounds that Scala is expecting that the static jMock method returnValue would be a val? What am I missing here?
Are you sure about the ';'?
one (nodeCtx).getParameter("FilenameRegex") will( returnValue(regex))
might work better.
In this example you see a line like:
expect {
one(blogger).todayPosts will returnValue(List(Post("...")))
}
with the following comment:
Specify what the return value should be in the same expression by defining "will" as Scala infix operator.
In the Java equivalent we would have to make a separate method call (which our favorite IDE may insist on putting on the next line!)
one(blogger).todayPosts; will(returnValue(List(Post("..."))))
^
|
-- semicolon only in the *Java* version
The OP explains it himself:
the returnValue static method was not visible, thus the errors.
And the will method just records an action on the latest mock operation, that's why it can be on the next line or after the semicolon :)
import org.jmock.Expectations
import org.jmock.Expectations._
...
context.checking(
new Expectations {
{ oneOf (nodeCtx).getParameter("FilenameRegex") will( returnValue(".*\\.data") ) }
}
)