Using variables in js.eval() function in scala js - scala.js

I am using javascript to fetch data from a text box using js.eval() function like :
val amount=js.eval("document.getElementById('amount').value;")
It is working fine when I am writing the id directly i.e. 'amount' in this case. But I want to create a function which will receive the id and then use the variable id.
I tried using '$' sign also like :
def getAmount(amount_id:String):Unit={
println("Amount is : "+js.eval(s"document.getElementById(${id}).value;"))
But it is not working. Any suggestions ?

Do not use js.eval. Use the interoperability features of Scala.js instead:
import org.scalajs.dom
import dom.html
def getAmount(amount_id:String): Unit = {
val input = dom.document.getElementById(amount_id).asInstanceOf[html.Input]
println(s"Amount is : ${input.value}")
}

Related

How to create global Javascript variable in Scala js?

I need to create global JS variable in my Scala js.
How this can be done?
Via Facade Type
Make an object that extends js.GlobalScope:
object MyGlobal extends js.GlobalScope {
var globalVar: String
}
Then, just assign to it:
MyGlobal.globalVar = "foo"
Via Dynamic interface
js.Dynamic.global.globalVar = "foo"
Caveat
Both of these methods need code to be executed before the variable is set to anything. There is currently no way to directly export a top-level value in Scala.js without executing code (see #1381).
If you want to export the g shortcut:
import scala.scalajs.js
import js.Dynamic.{ global => g }
g.myVar = "foo"

Google Picker using Scala.js

I'd like to use Google Picker in my Scala.js app. I need to convert this example somehow.
There are two main questions:
The first, how can I load and use https://apis.google.com/js/api.js in my Scala.js code to use gapi object?
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
The second, after a picker will be loaded, how can I access to the google.picker object to create the picker?
var picker = new google.picker.PickerBuilder()
As for any other JavaScript API, you can basically access it with a dynamically typed API using js.Dynamic or with a (possibly hand-written) typed facade.
In this case, I'd recommend the dynamic API for the first part:
import scala.scalajs.js
import js.Dynamic.{global => g, literal => lit}
g.gapi.load("auth", lit(callback = onAuthApiLoad))
g.gapi.load("picker", lit(callback = onPickerApiLoad))
and a static API for the second part:
#js.native
#JSName("google.picker.PickerBuilder")
class PickerBuilder() extends js.Object {
// here you can declare methods and fields of PickerBuilder
}
val picker = new PickerBuilder()

How to make Hive UDFs defined using the spark Interface show up in the SHOW FUNCTIONS list?

I am trying to register a Hive UDF. Compare the following two approaches:
Using the spark interface
sqlContext.registerFunction( "foobar", ( s : String ) => "foobar" )
Using the hive interface
#Description(
name = "foobar",
value = "_FUNC_(str) - foobars the string",
extended = "Example:\n" +
" foobar('baz') == 'foobar' "
)
class FooBarFunction extends UDF
{
def evaluate(s : Text) : Text = new Text("foobar")
}
sqlContext.sql("CREATE TEMPORARY FUNCTION foobar AS 'my.package.path.FooBarFunction'")
I would like to use the Spark interface which is much more convenient, especially when it comes to defining aggregations.
However, there are two (related) things that I could not figure out:
UDFs defined using "CREATE TEMPORARY FUNCTION" show up in the list generated by "SHOW FUNCTIONS". UDFs defined using the spark interface don't. Can I register the function somehow so that it does show up in the list?
I did not find a way to add a description to the function registered using the spark interface like I did with the #Description annotation. Is there any way to add this documentation?

Setting the property of an object using a variable value in scala

I'm trying to create a restful method to update data in the database, I'm using Scala on Play! framework. I have a model called Application, and I want to be able to update an application in the database. So the put request only requires the id of the application you want to update, then the optional properties you want to update.
So in my routes I have this:
PUT /v1/auth/application controllers.Auth.update_application(id: Long)
The method I currently have is this:
def update_application(id: Long) = Action { implicit request =>
var app = Application.find(id)
for((key, value) <- request.queryString) {
app."$key" = value(0)
//app.name = value(0)
}
val update = Application.update(id, app)
Ok(generate(
Map(
"status" -> "success",
"data" -> update
)
)).as("application/json")
}
In the method above I am looping through the request and the app object as a map instance, then updating the app model to be updated using the model. I know there is an easier way is to create the request string as map and just iterate through the object, but I am doing it this way for learning purposes. I'm new to Play! and Scala, barely a week new.
Is there a way to set a property using a variable dynamically that way? In the above method at the end of the loop that is how I would update a object's property in Groovy. So I'm looking for the equivalent in Scala. If Scala can't do this, what is the best way about going about accomplishing this task? Reflection? I don't want to over-complicate things
Play! provides play.api.data.Forms which allows creating a Form that uses the apply() and unapply() methods of a case class. Then you can call form.fill(app) to create a form with the initial state, bindFromRequest(request) to update the form with the request parameters, and get() to obtain a new instance with updated fields.
Define the form only once:
val appForm = Form(
mapping(
"field1" -> text,
"field2" -> number
)(Application.apply)(Application.unapply)
)
Then in your controller:
val app = appForm.fill(Application.find(id)).bindFromRequest(request).get
val update = Application.update(id, app)
Check out Constructing complex objects from the documentation.

Cannot access the parameter of a Menu.param from a Lift Snippet

I'm trying to extract the parameter from a Lift Menu.param within a snippet so that I can use it to create a named Comet. However, I get a NullPointerException when I try to pass the parameter to the snippet using SnippetDisptach in my Boot.scala, as suggested here:
http://comments.gmane.org/gmane.comp.web.lift/44299
I've created the Menu item as follows:
object AnItemPage {
// create a parameterized page
def menu = Menu.param[Item]("Item", "Item",
s => fetchItem(s), item => item._id.toString) / "item"
private def fetchItem(s:String) : Box[Item] = synchronized {
ItemDAO.findById(ObjectId.massageToObjectId(s))
}
}
I've added the menu to SiteMap. I've also created a Snippet which I would like to pick up the Item parameter. (I'm using fmpwizard's InsertNamedComet library here):
class AddCometItemPage(boxedItem: Box[Item]) extends InsertNamedComet with DispatchSnippet{
val item : Item = boxedItem.openOr(null)
override lazy val name= "comet_item_" + item._id.toString
override lazy val cometClass= "UserItemCometActor"
def dispatch = null
}
My next step is to crate an instance of this class as demonstrated by David Pollak here:
http://comments.gmane.org/gmane.comp.web.lift/44299
This is what I have added to my Boot.scala:
LiftRules.snippetDispatch.append {
case "item_page" => new AddCometItemPage(AnItemPage.menu.currentValue)
}
My item.html references this snippet:
<div class="lift:item_page">
I get the following null pointer exception when I compile and run this:
Exception occurred while processing /item/5114eb4044ae953cf863b786
Message: java.lang.NullPointerException
net.liftweb.sitemap.Loc$class.siteMap(Loc.scala:147)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.siteMap(Menu.scala:170)
net.liftweb.sitemap.Loc$class.allParams(Loc.scala:123)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.allParams(Menu.scala:170)
net.liftweb.sitemap.Loc$class.net$liftweb$sitemap$Loc$$staticValue(Loc.scala:87)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.net$liftweb$sitemap$Loc$$staticValue(Menu.scala:170)
net.liftweb.sitemap.Loc$$anonfun$paramValue$2.apply(Loc.scala:85)
net.liftweb.sitemap.Loc$$anonfun$paramValue$2.apply(Loc.scala:85)
net.liftweb.common.EmptyBox.or(Box.scala:646)
net.liftweb.sitemap.Loc$class.paramValue(Loc.scala:85)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.paramValue(Menu.scala:170)
net.liftweb.sitemap.Loc$$anonfun$currentValue$3.apply(Loc.scala:114)
net.liftweb.sitemap.Loc$$anonfun$currentValue$3.apply(Loc.scala:114)
net.liftweb.common.EmptyBox.or(Box.scala:646)
net.liftweb.sitemap.Loc$class.currentValue(Loc.scala:114)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.currentValue(Menu.scala:170)
bootstrap.liftweb.Boot$$anonfun$lift$8.apply(Boot.scala:107)
bootstrap.liftweb.Boot$$anonfun$lift$8.apply(Boot.scala:106)
net.liftweb.util.NamedPF$$anonfun$applyBox$1.apply(NamedPartialFunction.scala:97)
net.liftweb.util.NamedPF$$anonfun$applyBox$1.apply(NamedPartialFunction.scala:97)
net.liftweb.common.Full.map(Box.scala:553)
net.liftweb.util.NamedPF$.applyBox(NamedPartialFunction.scala:97)
net.liftweb.http.LiftRules.snippet(LiftRules.scala:711)
net.liftweb.http.LiftSession$$anonfun$net$liftweb$http$LiftSession$$findSnippetInstance$1.apply(LiftSession.scala:1506)
net.liftweb.http.LiftSession$$anonfun$net$liftweb$http$LiftSession$$findSnippetInstance$1.apply(LiftSession.scala:1506)
net.liftweb.common.EmptyBox.or(Box.scala:646)
net.liftweb.http.LiftSession.net$liftweb$http$LiftSession$$findSnippetInstance(LiftSession.scala:1505)
net.liftweb.http.LiftSession$$anonfun$locateAndCacheSnippet$1$1$$anonfun$apply$88.apply(LiftSession.scala:1670)
net.liftweb.http.LiftSession$$anonfun$locateAndCacheSnippet$1$1$$anonfun$apply$88.apply(LiftSession.scala:1669)
Has anybody any idea where I'm going wrong? I've not been able to find a lot of information on Menu.param.
Thank you very much for your help.
f
I have never tried what you are doing, so I am not sure the best way to accomplish it. The way you are using the Loc Param, you are extracting a variable from a URL pattern. In your case, http://server/item/ITEMID where ITEMID is the string representation of an Item, and which is the value that gets passed to the fetchItem function. The function call will not have a value if you just arbitrarily call it, and from what I can see you are requesting a value that is not initialized.
I would think there are two possible solutions. The first would be to use S.location instead of AnItemPage.menu.currentValue. It will return a Box[Loc[Any]] representing the Loc that is currently being accessed (with the parameters set). You can use that Loc to retrive currentValue and set your parameter.
The other option would be to instantiate the actor in your snippet. Something like this:
item.html
<div data-lift="AnItemPage">
<div id="mycomet"></div>
</div>
And then in your AnItemPage snippet, something like this:
class AnItemPage(item: Item) {
def render = "#mycomet" #> new AddCometItemPage(item).render
}
I haven't tested either of those, so they'll probably need some tweaking. Hopefully it will give you a general idea.