1

Im using Mapbox to Develop a mapping a app. The method I'm using uses a Point(Double, Double) Getting Type Mismatch Required: Double Found: Double?

        val lat = locationComponent.lastKnownLocation?.latitude?.toDouble()
        val lng = locationComponent.lastKnownLocation?.latitude?.toDouble()
        origin = Point.fromLngLat(lat, lng)
AlexT
  • 2,524
  • 1
  • 11
  • 23
  • The fact that you were using lat twice has nothing to do with `Getting Type Mismatch Required: Double Found: Double?` – AlexT Nov 26 '20 at 16:41

4 Answers4

4

The ? in your code on the values mean that those certain params can be null.

locationComponent.lastKnownLocation?.latitude?.toDouble()

This locationComponent.lastKnownLocation? means that lastKnownLocation can be null, and thus latitude can be null (latitude can also be null by itself, I don't know since I can't see the model).

Point.fromLngLat(lat, lng) does not accept null values, that means that you need to be cautious here.

You can fix this by checking the code to see if lastKnownLocation can truly be null, or is it just a non-annotated java param so the compiler doesn't how to treat it, so it plays it safe.

In that particular case (when you know for a fact that it can't be null) you can use !! to declare that value as not null (but this will throw a NPE if you are wrong).

You can also try and mitigate the risk by providing a default value, but then, what do you do with that default value? In what part of the world do you assign it to? Maybe you have other location components that would make sense, like the middle of the country of residence or etc (it all depends on the rest of your code).

val lat = locationComponent.lastKnownLocation?.latitude?.toDouble() ?: 0.0 
val lng = locationComponent.lastKnownLocation?.longitude?.toDouble() ?: 0.0 

Here, lat and lng will be set to 0.0 if they are null.

But depending on your cases you might actually want to not make that call when you don't have values. So you can try and check if they are null beforehand.

val lat = locationComponent.lastKnownLocation?.latitude?.toDouble()
val lng = locationComponent.lastKnownLocation?.longitude?.toDouble()

if(lat != null && lng != null) origin = Point.fromLngLat(lat, lng)

But in this scenario your origin is not set. But if those values can truly be null, then maybe that origin makes sense to not be set.

I strongly recommend that you read this: Null Safety in Kotlin

AlexT
  • 2,524
  • 1
  • 11
  • 23
  • Yes. OP, this is the right answer to read. Using `!!` masks potential bugs that will cost you time to hunt down later. Only use it if you're absolutely sure something cannot be null. Even then, it is preferable to use `?: error("useful error message")` instead of `!!`. – Tenfour04 Oct 15 '20 at 17:50
  • Yep, this pretty much covers it - don't use ``!!`` on stuff that actually could be null sometimes, and either handle it with default values, or by only doing the thing when you have valid data. – cactustictacs Oct 15 '20 at 18:37
  • 1
    And just to be clear, doing ``val whatever = thing.property?.value?.toDouble()`` will only return the result of ``toDouble()`` if every non-null check in the chain passes - otherwise a null will pop out. So an expression with ``?`` in it will always return a nullable type (you can catch that with our buddy Elvis ``?:`` and return a non-null value though) – cactustictacs Oct 15 '20 at 18:41
3

You are getting that error because Point.fromLngLat() expects a Double and not a Double?. A simple fix would be to cast Double to Double?, thereby initializing your origin variable this way:

origin = Point.fromLngLat(lat as Double, lng as Double)

Alternatively, you can use !! to "force" the variable to a non-nullable type like below:

origin = Point.fromLngLat(lat!!, lng!!)

NOTE:

If lat or lng is null in either scenario, the cast would fail and your app would crash from an NPE. A crude workaround is to check if either of them is null before casting.

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
  • 1
    I didn't know about using cast to do it. Nice one! =) – Henrique Vasconcellos Oct 15 '20 at 16:48
  • 1
    if we are going to throw safety away like that, why not do it the idiomatic way and use `!!` ? – AlexT Oct 15 '20 at 16:48
  • I see your point @Alex.T, It's a valid one too in the events that lat or lng is null. I guess Henrique's answer is more accurate. – Taslim Oseni Oct 15 '20 at 17:02
  • @TaslimOseni not sure about his answer as well, since we don't know what his process will do with that `origin`, it might create a massive hidden bug (the `!!` will only throw a NPE, so at least he knows where it fails). The "issue" I have with your answer is that it doesn't explain the dangers of using `!!` and/or when to use it. The `!!` can and will be valid in many if not most scenarios. – AlexT Oct 15 '20 at 17:05
  • I've updated my answer to fix that. Thanks for pointing that out. – Taslim Oseni Oct 15 '20 at 17:21
2

You can use !! to "force" it as a non nullable, or you can provide a "if null value".

Using the !!:

val lat = locationComponent.lastKnownLocation?.latitude?.toDouble()
val lng = locationComponent.lastKnownLocation?.latitude?.toDouble()
origin = Point.fromLngLat(lat!!, lng!!)

using a default value:

val lat = locationComponent.lastKnownLocation?.latitude?.toDouble()
val lng = locationComponent.lastKnownLocation?.latitude?.toDouble()
origin = Point.fromLngLat(lat?: 0.0, lng?: 0.0)
Henrique Vasconcellos
  • 1,144
  • 1
  • 8
  • 13
1

Unfortunately, I cannot comment yet. I just want to add to the already correct answers that defaulting to Double.NaN is also an option that may be preferable.

philuX
  • 191
  • 1
  • 3