unable to use WS.url() in Play app tutorial - scala

I am doing a tutorial for Play framework with Scala. I am quite early into the tutorial and i am having a problem with ws. In my class WS is not recognized although that says to use WS.url("url-here") and to import play.api.libs._ which i have done both. I have also tried using ws.url("url-here") as well... and here wsis recognized but after that i get a "can't resolve symbol 'url'". Here is my build.sbt:
name := """play_hello"""
organization := "x.x"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.3"
libraryDependencies ++= Seq(
"org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test,
"com.ning" % "async-http-client" % "1.9.29",
guice,
ws
)
And here is the code for my class:
package controllers
import javax.inject.Inject
import com.ning.http.client.oauth.{ConsumerKey, RequestToken}
import play.api.Play.current
import play.api.libs._
import play.api.mvc._
import scala.concurrent.Future
class Application #Inject()(cc: ControllerComponents) extends
AbstractController(cc){
def tweets = Action.async{
credentials.map { case (consumerKey, requestToken) =>
WS.url("http://stream.twitter.com")
Future.successful{
Ok
}
}getOrElse{
Future.successful{
InternalServerError("Twitter credentials are missing!")
}
}
}
def credentials: Option[(ConsumerKey, RequestToken)] = for{
apiKey <- current.configuration.getString("twitter.apiKey")
apiSecret <- current.configuration.getString("twitter.apiSecret")
token <- current.configuration.getString("twitter.token")
tokenSecret <- current.configuration.getString("twitter.tokenSecret")
}yield (
new ConsumerKey(apiKey, apiSecret),
new RequestToken(token, tokenSecret)
)
}
I Figure that most likely this is some type of problem with a dependency conflict. Here is a screenshot of ws related libraries in project structure. I would appreciate any help in finding a solution to this. Thank you.

The solution was to add ws: WSClient to the parameters of Application class constructor. Apperently standalone WS object has been removed in more recent versions of ws library.
class Application #Inject()(cc: ControllerComponents, ws: WSClient) extends AbstractController(cc)
Now i can use:
ws.url("https://stream.twitter.com/1.1/statuses/filter.json")
Also according to the documentation on play website if you for some reason can not use an injected WSClient, then you can create an instance of one and use that.

Related

How to use jquery-ui with JSImport

I want to access the jquery ui library in my scala js project. I have tried defining the following main module:
import org.scalajs.jquery.JQueryStatic
import scala.scalajs.js
import org.scalajs.dom
import scalatags.JsDom.all._
import scala.scalajs.js.annotation.JSImport
#JSImport("jquery", JSImport.Namespace)
#js.native
object JQuery extends JQueryStatic
#js.native
trait JQueryUI extends JQueryStatic {
def spinner(options: js.Object = js.Dynamic.literal()): JQueryUI = js.native
}
#JSImport("jquery-ui", JSImport.Namespace)
#js.native
object JQueryUI extends JQueryUI
object App {
def main(args: Array[String]): Unit = {
dom.document.getElementById("root").appendChild(div(input(id := "input")).render)
JQuery("#input").asInstanceOf[JQueryUI].spinner()
}
}
And my build.sbt is as follows:
enablePlugins(ScalaJSBundlerPlugin)
lazy val opexCounter = project.in(file(".")).settings(
name := "Repro",
scalaVersion := "2.12.8",
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-dom" % "0.9.6",
"com.lihaoyi" %%% "scalatags" % "0.6.7",
"be.doeraene" %%% "scalajs-jquery" % "0.9.4"
),
npmDependencies in Compile ++= Seq(
"jquery" -> "2.2.1",
"jquery-ui" -> "1.12.1",
),
mainClass in Compile := Some("App"),
scalaJSUseMainModuleInitializer := true,
webpackDevServerPort := 3000
)
But when I load my page I get the following error in my console:
TypeError: qual$1.spinner is not a function
Is this not the correct way to import the library and if not what is?
The complete source for the project can be found here
I changed my npm dependency from jquery-ui to jquery-ui-bundle and imported it. I also had to make an explicit reference to my JQueryUIImport object in order to ensure it was instantiated. Those 2 changes fixed the problem

object evolutions is not a member of package play.api.db.slick

I'm a newbie to Play framework and can't figure out why I'm getting this error in my application loader class that I copied and pasted from the Play 2.6 documention here with some modifications for new versions of slick and slick-evolutions.
Here is the part of my build.sbt that references the libraries:
scalaVersion := "2.12.2"
libraryDependencies ++= Seq(evolutions, jdbc)
libraryDependencies ++= Seq(jdbc, ehcache , ws , specs2 % Test , guice )
libraryDependencies ++= Seq("com.typesafe.play" %% "play" % "2.6.11")
libraryDependencies += "com.typesafe.play" %% "play-slick" % "3.0.1"
libraryDependencies += "com.typesafe.play" %% "play-slick-evolutions" % "3.0.1"
libraryDependencies ++= Seq("mysql" % "mysql-connector-java" % "5.1.36")
Here is my application.conf
play.application.loader=AppComponents
And here is the AppComponents class which I put in my root directory
import play.api.ApplicationLoader.Context
import play.api.BuiltInComponentsFromContext
import play.api.db.{Database, DBComponents, HikariCPComponents}
import play.api.db.slick.evolutions.{SlickEvolutionsComponents}
import play.api.routing.Router
import play.filters.HttpFiltersComponents
class AppComponents(cntx: Context)
extends BuiltInComponentsFromContext(cntx)
with DBComponents
with SlickEvolutionsComponents
with HikariCPComponents
with HttpFiltersComponents
{
// this will actually run the database migrations on startup
applicationEvolutions
}
I've examined the play-slick-evolutions_2.12-3.0.1.jar jar that was downloaded and it indeed has has play.api.db.slick.evolutions there. I've also tried earlier versions that comport exactly with the code in the Play 2.6 documentation, but there too, evolutions is not a member of the package.
First, a project rebuild took care of the initial error, but it did not solve the problem with the Application Loader. To fix this I returned to the Play 2.6 documentation and restored the class to the segment they provided and removed the play-slick sbt entries, restoring to the entries in the documentation. There was still a problem, and on finding another example it became evident that I didn't have a complete class. Here it is:
import play.api.ApplicationLoader
import play.api.ApplicationLoader.Context
import play.api.BuiltInComponentsFromContext
import play.api.db.{Database, DBComponents, HikariCPComponents}
import play.api.db.evolutions.EvolutionsComponents
import play.api.routing.Router
import play.filters.HttpFiltersComponents
class MyApplicationLoader extends ApplicationLoader {
def load(context: Context) = {
new MyComponents(context).application
}
}
class MyComponents(cntx: Context)
extends BuiltInComponentsFromContext(cntx)
with DBComponents
with EvolutionsComponents
with HikariCPComponents
with HttpFiltersComponents
{
// this will actually run the database migrations on startup
lazy val router = Router.empty
applicationEvolutions
}
I also adjusted my application.conf setting to:
play.application.loader=MyApplicationLoader
Note that I still need to add the routing because the lazy val router = Route.empty gives a web page that says:
Action Not Found
For request 'GET /'
These routes have been tried, in this order:

How to use a standalone WSClient in a Scala application

I would like to use ws in a standalone application. Trying this code, copied from https://gist.github.com/cdimascio/46b2b7d2986636c1189c :
import com.ning.http.client.AsyncHttpClientConfig
import play.api.libs.ws.ning._
import play.api.libs.ws._
// provide an execution context
import scala.concurrent.ExecutionContext.Implicits.global
object WSStandaloneTest {
def main(args: Array[String]) {
// set up the client
val config = new NingAsyncHttpClientConfigBuilder(DefaultWSClientConfig()).build
val builder = new AsyncHttpClientConfig.Builder(config)
val client = new NingWSClient(builder.build)
// execute a GET request
val response = client.url("http://www.example.com").get
// print the response body
response.foreach(r => {
println(r.body)
// not the best place to close the client,
// but it ensures we dont close the threads before the response arrives
// Good enough for the gist :-D
client.close()
})
}
}
Results in the following error:
[error] object ning is not a member of package play.api.libs.ws
[error] import play.api.libs.ws.ning._
In my build.sbt I have this:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.1"
libraryDependencies += "com.typesafe.play" %% "play-ws" % "2.6.1"
What am I doing wrong?
NingWSClient is deprecated in Play! 2.5.x.
In 2.6.x
The ning package has been replaced by the ahc package, and the Ning* classes replaced by AHC*.
There is a migration guide available in the official doc.
So you can choose to downgrade to 2.5.x and use ning or update the code.

Get content from Akka ResponseEntity in Scala

I do a GET HTTP call to a rest service which returns a json. I would like to parse the json to a scala object but here I got stuck. I am using the Akka api and I can't manage to retrieve the content from the Akka's ResponseEntity
Here is my sbt file:
name := "ScalaHttp"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++={
val akkaV = "2.4.5"
Seq(
"com.typesafe.akka" %% "akka-http-core" % akkaV,
"com.typesafe.play" %% "play-json" % "2.4.0-M3"
)
}
And here is the app
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpRequest
import akka.stream.ActorMaterializer
import scala.concurrent.ExecutionContext.Implicits.global
object Sender {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
Http().singleRequest(HttpRequest(uri = "http://declinators.com/declinator?noun=komunikacja")) foreach {
y => println(y.entity)
println(y.entity.getContentType())
println(y.entity.contentType)
}
}
}
This prints:
HttpEntity.Strict(application/json,{"nominative":"komunikacja","genitive":"komunikacji","dative":"komunikacji","accusative":"komunikacjÄ™","instrumental":"komunikacjÄ…","locative":"komunikacji","vocative":"komunikacjo"})
application/json
application/json
Here come the questions:
1. Why ResponseEntity supplies getContentType() and contentType()? They return the same thing.
2. Getting the contentyType is easy, you have two ways for doing it, but how can I get the content itself, so I can play (i.e. parse it using play) with the json!
You can use entity.data.toString for Binary content type, or the following code piece
data.decodeString(nb.charset.value)
Please follow the HttpEntity.Strict.toString implementation here for detail:
https://github.com/akka/akka/blob/master/akka-http-core/src/main/scala/akka/http/scaladsl/model/HttpEntity.scala#L316

value resolveOne is not a member of akka.actor.ActorSelection

I get the above error message from here:
implicit val askTimeout = Timeout(60 seconds)
val workerFuture = workerContext actorSelection(payload.classname) resolveOne()
val worker = Await.result(workerFuture, 10 seconds)
worker ask Landau(List("1", "2", "3"))
specifically from the second line.. the import made is
import akka.actor._
import akka.util.Timeout
import akka.pattern.{ ask, pipe }
import scala.concurrent.duration._
import scala.concurrent.Await
import java.util.concurrent.TimeUnit
akka version is 2.2.1 and scala is 2.10.2, i'm using sbt 0.13 to build it all..
I cannot really understand what's wrong, since resolveOne is definetely coming from that package..
EDIT: I made a print of all the methods of the class with
ActorSelection.getClass.getMethods.map(_.getName).foreach { p => println(p)}
and this is the result:
apply
toScala
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
I had the same problem and changed my Scala and Akka versions as described in the link below.
I brought here part of my build.sbt for simplicity:
scalaVersion := "2.10.4"
resolvers += "Akka Snapshot Repository" at "http://repo.akka.io/snapshots/"
libraryDependencies ++= Seq("com.typesafe.akka" %% "akka-actor" % "2.4-SNAPSHOT")
link: http://doc.akka.io/docs/akka/snapshot/intro/getting-started.html