Home > Software engineering >  java.lang.NumberFormatException: For input string: "null" at jdk.internal.math.FloatingDec
java.lang.NumberFormatException: For input string: "null" at jdk.internal.math.FloatingDec

Time:10-18

I tried to pass data from DetailActivity to PaymentActivity, but I got this error Here is the error and here is PaymentFragment after I comment textview that contain number format on it here it is. The user data pass successfully, but the product data unsuccess to pass I think. So how to pass the product data from DetailActivity to PaymentActivity

here is my code: Helpers File

object Helpers {

    fun getDefaultGson(): Gson {
        return GsonBuilder()
            .excludeFieldsWithoutExposeAnnotation()
            .setDateFormat(Cons.DATE_FORMAT_SERVER)
            .registerTypeAdapter(Date::class.java, JsonDeserializer { json, _, _ ->
                val formatServer = SimpleDateFormat(Cons.DATE_FORMAT_SERVER, Locale.ENGLISH)
                formatServer.timeZone = TimeZone.getTimeZone("UTC")
                formatServer.parse(json.asString)
            })
            .registerTypeAdapter(Date::class.java, JsonSerializer<Date> { src, _, _ ->
                val format = SimpleDateFormat(Cons.DATE_FORMAT_SERVER, Locale.ENGLISH)
                format.timeZone = TimeZone.getTimeZone("UTC")
                if (src != null) {
                    JsonPrimitive(format.format(src))
                } else {
                    null
                }
            })
            .create()
    }

    fun Throwable.getErrorBodyMessage(): String {
        return if (this is HttpException) {
            val errorCode = this.code()
            if (errorCode == 405) {
                "Method yang digunakan salah"
            } else if (errorCode == 503) {
                "Error Server"
            } else {
                val parseErrorBody = this.response()?.errorBody()!!.parseErrorBody()
                if (parseErrorBody?.meta?.message == null) {
                    "Permintaan anda belum berhasil di proses. Silakan coba kembali"
                } else {
                    parseErrorBody?.meta?.message.toString()
                }
            }

        } else if (this is ConnectException || this is UnknownHostException) {
            "Maaf Anda sedang Offline. Silakan coba kembali"

        } else {
            return if (this.message == null)
                "Permintaan anda belum berhasil di proses. Silakan coba kembali"
            else if (this.message.equals(""))
                ""
            else
                this.message!!

        }
    }

    fun ResponseBody.parseErrorBody(): Wrapper<*>? {
        val gson = Gson()
        val adapter = gson.getAdapter(Wrapper::class.java)
        try {
            return adapter.fromJson(string())
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return null
    }

    fun TextView.formatPrice(value: String) {
        this.text = getCurrencyIdr(java.lang.Double.parseDouble(value))
    }

    fun getCurrencyIdr(price: Double): String {
        val format = DecimalFormat("#,###,###")
        return "Rp. "   format.format(price).replace(",".toRegex(), ".")
    }

    fun Long.convertLongToTime(formatTanggal: String): String {
        val date = Date(this)
        val format = SimpleDateFormat(formatTanggal)
        return format.format(date)
    }

}

PaymentFragment: class PaymentFragment : Fragment(), PaymentContract.View {

var progressDialog: Dialog? = null
var total : Int = 0
lateinit var presenter: PaymentPresenter

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?, savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_payment, container, false)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    (activity as DetailActivity?)!!.toolbarPayment()

    var data = arguments?.getParcelable<Data>("data")
    initView(data)

    initView()
    presenter = PaymentPresenter(this)

}

private fun initView(data: Data?) {
    tvTitle.text = data?.name
    tvPrice.formatPrice(data?.price.toString())
    Glide.with(requireContext())
        .load(data?.picturePath)
        .into(tvPoster)

    tvNameItem.text = data?.name
    tvHarga.formatPrice(data?.price.toString())

    if (!data?.price.toString().isNullOrEmpty()) {
        var totalTax = data?.price?.div(10)
        tvTax.formatPrice(totalTax.toString())

        total = data?.price!!   totalTax!!   50000
        tvTotalPrice.formatPrice(total.toString())
    } else {
        tvPrice.text = "IDR. 0"
        tvTax.text = "IDR. 0"
        tvTotalPrice.text = "IDR. 0"
        total = 0
    }

    var user = IcaCraft.getApp().getUser()
    var userResponse = Gson().fromJson(user, User::class.java)

    tvNameDeliver.text = userResponse?.name
    tvPhoneDeliver.text = userResponse?.phoneNumber
    tvAddressDeliver.text = userResponse?.address
    tvHouseNo.text = userResponse?.houseNumber
    tvCityDeliver.text = userResponse?.postalCode

    btn_CheckoutNow.setOnClickListener {
        presenter.getCheckout(
            data?.id.toString(),
            userResponse?.id.toString(),
            "1",
            total.toString(), it
        )
    }

}

private fun initView() {
    progressDialog = Dialog(requireContext())
    val dialogLayout = layoutInflater.inflate(R.layout.dialog_loader, null)

    progressDialog?.let {
        it.setContentView(dialogLayout)
        it.setCancelable(false)
        it.window?.setBackgroundDrawableResource(android.R.color.transparent)
    }
}

override fun onCheckoutSuccess(checkoutResponse: CheckoutResponse, view: View) {
    val i = Intent(Intent.ACTION_VIEW)
    i.data = Uri.parse(checkoutResponse.paymentUrl)
    startActivity(i)

    Navigation.findNavController(view).navigate(R.id.action_fragmentPayment_to_fragmentPaymentSuccess)
}

override fun onCheckoutFailed(message: String) {
    Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
}

override fun showLoading() {
    progressDialog?.show()
}

override fun dismissLoading() {
    progressDialog?.dismiss()
}

}

DetailActivity:

class DetailFragment : Fragment() {

    var data:Data?= null
    var bundle:Bundle?= null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_detail, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        (activity as DetailActivity?)!!.toolbarDetail()

        arguments?.let {
            DetailFragmentArgs.fromBundle(it).data?.let {
                initView(it)
            }
        }

        btnOrderNow.setOnClickListener { view ->
            Navigation.findNavController(view).navigate(R.id.action_fragmentDetail_to_fragmentPayment, bundle)

        }
    }

    private fun initView(data: Data?) {

        data?.let {
//            bundle = bundleOf("data" to data)

            Glide.with(requireContext())
                .load(it.picturePath)
                .into(ivPoster)

            tvTitle.text = it.name
            tvDescription.text = it.description
            tvMaterials.text = it.materials

            tvTotal.formatPrice(it.price.toString())
        }
    }
}

CodePudding user response:

I am not sure about the bug in the code but there are many other ways you can share data in between activities. Try using viewModel to share data between your activities. SharedPreferences are another way too. There are plenty of other ways but I think viewModel is the best way. I personally find it difficult to transfer data between fragments using arguments. So Good Luck!

CodePudding user response:

Your code is a bit complicated but the error is understandable. It says "You can not parse null to double". You define "price" as "Int?", so it can be "null" and when it is null, app crashes. This can be solved by doing the followings:
1- You can define your price "not null" and set a default value as 0.

@Expose
@SerializedName("price")
val price: Int = 0

2- If you do not want to change your data class, you need to control what to pass to "parseDouble()" method.

fun TextView.formatPrice(value: String) {
        if (value != null) {
           this.text = getCurrencyIdr(java.lang.Double.parseDouble(value))
        } else {
           this.text = getCurrencyIdr(0.0) // we didn't parse the null
        }
        
    }

If one of these individually will not solve your error try both, it has to solve it.

  • Related