What is the best way to right the code? I have one...
# codingconventions
k
What is the best way to right the code? I have one variable like this ->
Copy code
val filter: QueryFilter? = null
and I have one class like this ->
Copy code
class QueryFilter(val by: String, val operator: String, val value: String)
And I am using the variable with class like this ->
Copy code
filter.let {
                    mapOf(Pair("q[${<http://it.by|it.by>}_${it.operator}]", it.value))
                } ?: emptyMap()
But now I have a variable like this
Copy code
val filter: Array<QueryFilter> = emptyArray()
then how to use the loop with filter function with the same class? I want to know that is this the correct way to write a code ? or Is there any better way to write the below code?
Copy code
filter.let { it ->
                    it.forEach {
                        mapOf(Pair("q[${<http://it.by|it.by>}_${it.operator}]", it.value))
                    }
                }
            }) as Map<String, String>
t
So first: your first filter property is nullable, so you probably meant to do
?.let
. The
.let
call in your last code snippet is obsolete, because you're only using it once to call
forEach
. Also, your
forEach
lambda shadows the
it
which makes code more confusing. Also the cast in the end wouldn't work, because forEach just returns Unit. what you probably mean to do is this:
Copy code
filter.associate { Pair("q[${<http://it.by|it.by>}_${it.operator}]", it.value) }
or to make it even a bit more "kotliny" but still doing exactly the same thing
Copy code
filter.associate { "q[${<http://it.by|it.by>}_${it.operator}]" to it.value }
k
@Tobias Berger So in the first part of code I am using the
val filter: QueryFilter? = null
because I know I have only QueryFilter data but now the requirement is we have to use ArrayOfQueryFilter with assigning the empty array
val filter: Array<QueryFilter> = emptyArray()
. So now I have to use forloop to get all the query filter data so I modified like below code (More readable format)
Copy code
filter.let { it: Array<QueryFilter> ->
                    it.forEach {
                        mapOf(Pair("q[${<http://it.by|it.by>}_${it.operator}]", it.value))
                    }
                }
            }) as Map<String, String>
Getting the error while removing the old code and using the new code which was shared by you
Copy code
Type mismatch.
Required:
Map<String, String>
Found:
() → Map<String, String>
t
the for-loop creates some maps but doesn't do anything with them. The cast in the end will not work, because the forEach call (and the let call) returns Unit, not a map. Also, like I said, the let-call is obsolete if you only use the receiver once. It makes no difference if you do
filter.let { it.forEach { ... } }
or just
filter.forEach { ... }
and usually IntelliJ will actually tell you that. The code I posted should produce a Map, not a lambda returning a map. can you show a more complete snippet of code that shows how you're using it?
k
Copy code
sealed class Api : JsonApi() {
    // API endpoints
    data class Index(val accountId: String, val filter: Array<QueryFilters> = emptyArray()) : Api()

    // JsonApi implementation
    override val baseUrl: String
        get() = "COMPANY URL"

    override val subpath: String
        get() = when (this) {
            is Index -> "data/$accountId/index"
        }

    override val method: HttpMethod
        get() = when (this) {
            is Index -> HttpMethod.Get
        }

    override val headers: Map<String, String>
        get() = emptyMap()

    override val queryParameters: Map<String, String>
        get() = when (this) {
            is Index -> ({
                filter.let { it ->
                    it.forEach {
                        mapOf(Pair("q[${<http://it.by|it.by>}_${it.operator}]", it.value))
                    }
                }
            }) as Map<String, String>
        }
}

class QueryFilters(val by: String, val operator: String, val value: String)
This queryParameters is a override method so adding the below part of code where we are creating the function and using the
queryParameters
with for loop line number
3.
Copy code
1. private fun buildRequestUrl(): URL {
2.        val uriBuilder = Uri.parse(baseUrl).buildUpon()
3.        for ((key, value) in queryParameters) {
4.            uriBuilder.appendQueryParameter(key, value)
5.        }
6.        return URL(uriBuilder.build().toString())
7.    }
t
works fine if you use my code:
Copy code
override val queryParameters: Map<String, String>
    get() = when (this) {
        is Index -> filter.associate { "q[${<http://it.by|it.by>}_${it.operator}]" to it.value }
    }
you probably tried this:
Copy code
override val queryParameters: Map<String, String>
    get() = when (this) {
        is Index -> ({ filter.associate { "q[${<http://it.by|it.by>}_${it.operator}]" to it.value } })
    }
That wraps the code in a lambda body instead of calling it
👍 1
k
Thanks 🙂 for the help & your time to help me learn something new 🙂