Reputation: 8291
I want to implement a class with two constrcutors. And empty constructor and another with a param user:FirebaseUser
But i'm getting the message error:
"There is a cycle in the delegation change"
class UserModel(user: FirebaseUser) {
var uid: String?
val email: String?
val phoneNumber: String?
val photoUrl: String
val displayName: String?
//error message: There is a cycle in the delegation change
constructor():this() {}
init {
this.displayName = user.displayName
this.email = user.email
this.phoneNumber = user.phoneNumber
this.photoUrl = user.photoUrl!!.toString()
this.uid = user.uid
}
companion object {
@Exclude
val CURRENT_LOCATION = "location"
}
}
I've tried several approaches without success. Any help?
Upvotes: 0
Views: 4060
Reputation: 28228
All the secondary constructors have to call the primary constructor, either directly or indirectly. Which means:
class X(var x: Int){
constructor() : this(0.0);
constructor(x: Double) : this(x.toInt());
}
However, you can't do this:
class X(var x: Int){
constructor() : this();
constructor(x: Double) : this();
}
Because it would result in a Stack Overflow Exception.
The above example is horrible code, but it's just as a demo.
So with this line:
constructor():this() {}
You make the secondary constructor call itself.
Instead, call the primary constructor. This means you need to pass a FirebaseUser
as an argument. I'm not familiar with Firebase, so I'll leave that to you.
But as an example, you basically need to do this instead:
constructor() : this(FirebaseUser());
Either initialize directly, or get it from a method. If you can't get one, you could of course just make it nullable.
But if you're dealing with nullables, assuming the majority of your code is in Kotlin, you can just make it nullable with a default value and remove the secondary constructor:
class UserModel(user: FirebaseUser? = null){
init{
// Now that `user` is nullable, you need to change the assignments to include null-safe or non-null assertion (?. or !!. respectively)
}
}
Upvotes: 2
Reputation: 89538
You have to call into the primary constructor from every secondary constructor you have, since its parameters may be used in property initializers and initializer blocks, like you've used user
in the init
block in your code.
With this code, the secondary constructor just recursively calls itself:
constructor() : this() {}
What you should do instead is call into the primary constructor so that the class' properties can be initialized:
constructor() : this(FirebaseUser()) {} // get FirebaseUser from somewhere
Alternatively, if what you meant to do is leave everything null
when the secondary no-param constructor is called, you could opt for something like this:
class UserModel(user: FirebaseUser?) {
var uid: String? = user?.uid
val email: String? = user?.email
val phoneNumber: String? = user?.phoneNumber
val photoUrl: String? = user?.photoUrl?.toString()
val displayName: String? = user?.displayName
constructor() : this(null)
}
Upvotes: 1