Home > Blockchain >  No value passed for parameter string
No value passed for parameter string

Time:01-06

I am doing an application in Kotlin, where questions are added to the DB. I am getting an error like: no value passed for parameter string

if (cursor.moveToFirst()) {
    do {
        val question = Question() //this line gives the error
        question.setID(cursor.getString(0).toInt())
        question.setQuestion(cursor.getString(1))
        question.setOption1(cursor.getString(2))
        question.setOption2(cursor.getString(3))
        question.setOption3(cursor.getString(4))
        question.setOption4(cursor.getString(5))
        question.setAnswer(cursor.getString(6))
        // Adding contact to list
        questionList.add(question)
    } while (cursor.moveToNext())
}

Question Class

class Question(
    toInt: Int,
    string: String,
    string1: String,
    string2: String,
    string3: String,
    string4: String,
    string5: String
) {
    var _id = 0
    var _question: String? = null
    var _option1: String? = null
    var _option2: String? = null
    var _option3: String? = null
    var _option4: String? = null
    var _answer: String? = null
    fun Question() {}
    fun Question(
        id: Int,
        question: String?,
        option1: String?,
        option2: String?,
        option3: String?,
        option4: String?,
        _answer: String?
    ) {
        _id = id
        _question = question
        _option1 = option1
        _option2 = option2
        _option3 = option3
        _option4 = option4
        this._answer = _answer
    }

    fun Question(
        question: String?,
        option1: String?,
        option2: String?,
        option3: String?,
        option4: String?,
        _answer: String?
    ) {
        _question = question
        _option1 = option1
        _option2 = option2
        _option3 = option3
        _option4 = option4
        this._answer = _answer
    }

    fun getID(): Int {
        return _id
    }

    fun setID(id: Int) {
        _id = id
    }

    fun getQuestion(): String? {
        return _question
    }

    fun setQuestion(question: String?) {
        _question = question
    }

    fun getOption1(): String? {
        return _option1
    }

    fun setOption1(option1: String?) {
        _option1 = option1
    }

    fun getOption2(): String? {
        return _option2
    }

    fun setOption2(option2: String?) {
        _option2 = option2
    }

    fun getOption3(): String? {
        return _option3
    }

    fun setOption3(option3: String?) {
        _option3 = option3
    }

    fun getOption4(): String? {
        return _option4
    }

    fun setOption4(option4: String?) {
        _option4 = option4
    }

    fun getAnswer(): String? {
        return _answer
    }

    fun setAnswer(answer: String?) {
        _answer = answer
    }
}

This line is giving me the error

val question = Question()

CodePudding user response:

First, it seems you are trying to create some extra constructors with the syntax

fun Question() {

but this is not the syntax for a constructor. It is a regular member function named Question and can only be called on an already existing instance of a Question. The correct syntax would be:

constructor() {

However, since you have a primary constructor, this would be a secondary constructor and would have to call the primary constructor with the arguments it requires, which is going to be super complicated for your case.

Your Question class is extremely overdesigned. In Kotlin:

  1. There is no reason to have setter functions since we have properties instead of fields. Any setter function is redundant to the capabilities of a property, so there is no reason to pollute your code with them.

  2. You can put properties directly in the primary constructor. Then you don't have to manually assign constructor parameters to property values.

  3. You can give parameters default values so you don't have to create special constructors that represent empty conditions.

With the above features of Kotlin, you can rewrite your entire class like this, with no loss of functionality or flexibility:

data class Question (
    var id = 0,
    var question: String? = null,
    var option1: String? = null,
    var option2: String? = null,
    var option3: String? = null,
    var option4: String? = null,
    var answer: String? = null
)

At your use site, you can call this empty constructor and then set the properties on it like you were trying to do. Properties in Kotlin should be set with assignment syntax (=), not setter functions. You can also use the apply scope function to avoid having to write question. over and over:

if (cursor.moveToFirst()) {
    do {
        val question = Question().apply {
            id = cursor.getString(0).toInt()
            question = cursor.getString(1)
            option1 = cursor.getString(2)
            option2 = cursor.getString(3)
            option3 = cursor.getString(4)
            option4 = cursor.getString(5)
            answer = cursor.getString(6)
        }
        // Adding contact to list
        questionList.add(question)
    } while (cursor.moveToNext())
}

However, it looks like you have no reason to make any of these parameters nullable. You should avoid nullable parameters whenever possible, because they are harder to work with. If a Question in your app always has values for all these properties, they should not be nullable, and you don't need to provide default values. I would define your class like this:

data class Question (
    val id: Int,
    val question: String,
    val option1: String,
    val option2: String,
    val option3: String,
    val option4: String,
    val answer: String
)

Then at the usage site, you can call this constructor with all the arguments directly:

if (cursor.moveToFirst()) {
    do {
        val question = Question(
            id = cursor.getString(0).toInt(),
            question = cursor.getString(1),
            option1 = cursor.getString(2),
            option2 = cursor.getString(3),
            option3 = cursor.getString(4),
            option4 = cursor.getString(5),
            answer = cursor.getString(6)
        )
        // Adding contact to list
        questionList.add(question)
    } while (cursor.moveToNext())
}

By the way, this if/do/while pattern for traversing the cursor is unnecessarily complicated. A cursor starts at a position before the first item, so you don't need to move it to first or use do/while. It would be equivalent to use:

while (cursor.moveToNext()) {
    val question = Question(
        id = cursor.getString(0).toInt(),
        question = cursor.getString(1),
        option1 = cursor.getString(2),
        option2 = cursor.getString(3),
        option3 = cursor.getString(4),
        option4 = cursor.getString(5),
        answer = cursor.getString(6)
    )
    // Adding contact to list
    questionList.add(question)
}

CodePudding user response:

You have to initialize Question class constructor parameters value to default or null.

For example,

class Question(
    toInt: Int = 0,
    string: String = "",
    string1: String = "",
    string2: String = "",
    string3: String = "",
    string4: String = "",
    string5: String = ""
) {
     //Your code here
}

OR

class Question(
    toInt: Int? = null,
    string: String? = null,
    string1: String? = null,
    string2: String? = null,
    string3: String? = null,
    string4: String? = null,
    string5: String? = null
) {
     //Your code here
}
  •  Tags:  
  • Related