2

I'm new to scala.js and having some trouble wrapping my head around it. Currently I'm stuck with the following (the non-async flag is intentional):

val req = jQuery.ajax(literal(
    url = ...,
    `type` = "GET",
    async = false).asInstanceOf[JQueryAjaxSettings]
)
val res = req.selectDynamic("responseText").toString

Actually, the response is a JSON-Array. Each item in the array has a field called name (among other fields), this is guaranteed and does not have to be validated. What I want to do is to .map each entry to its name field, so that the resulting output is an Array[String] containing only the names of the elements. How can I achieve that?

1 Answer 1

3

Hmm. Keep in mind that the async flag is long since deprecated; I hadn't realized that it was even available any more. But taking that as read, here's roughly what's involved. (Obviously untested; adapt as needed to the reality of your situation.)

My impression from your description is that the result is a JSON string, which is actually encoding an array. That being the case, the first step is to parse that:

val rawArray:js.Dynamic = JSON.parse(res)

That parses the JSON string, and gives you a js.Dynamic, which is the "raw" form of a JS object. At this point, Scala.js knows nothing about its structure.

Next, you should describe to Scala.js what the structure of each element of your array looks like:

@js.native
trait MyStruct extends js.Object {
  val name:String = js.native
}

This is how you instruct Scala.js about a JavaScript type. You're telling it that this type has a property named "name", which is a String. You can add the other fields of the type or not, as you prefer -- since it sounds like you only care about name, you don't need to list the rest.

Then, you tell Scala.js what your rawArray really is:

val myArray = rawArray.asInstanceOf[js.Array[MyStruct]]

asInstanceOf doesn't change anything -- it is just declaring to Scala.js, "I know that this js.Dynamic is actually an Array of MyStruct". So now you have myArray, which is a js.Array[MyStruct], and you can use map as normal:

val myNames = myArray.map(_.name)

This sort of stuff is pretty normal when you're operating at the boundary of Scala.js and raw JavaScript. Since the JS level is completely untyped, and the SJS level is strongly typed, you have to "teach" SJS what the actual types coming out of the JS level are. Then you can just assume those types in the rest of the SJS code...

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that looks promising. I'm busy at the moment but will have a look into it within the next couple of days.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.