0

I'm accessing a WordPress API to fetch the posts using Retrofit2, then when I try to assign the values to the views in my adapter:

inner class MainActivityViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    fun bind(post: Post) {
        with(post) {
            itemView.tv_post_title.text = title
            itemView.tv_post_date.text = date
            itemView.tv_post_content.text = content
        }
    }
}

The Retrofit's GET returns an Observable, and thus, the following error in onErrorResumeNext is shown when it tries to assign:

java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 373 path $[0].title

This is because title key has a rendered key within it:

{  
  id:497,
  date:"2018-04-08T03:34:12",
  [...]
  title:{  
    rendered:"Lorem ipsum dolor sit amet"
  }
}

The same applies to content and excerpt. How do I access these rendereds keys? I tried something like

val title: JsonElement = JsonParser().parse(post.title)

but the same error persists.

1 Answers1

1

This happening because json parser is not able to parse the title object.

java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 373 path $[0].title

To avoid this runtime error, click here to create java pojo for expected json and then use it as return type in your retrofit api.

Try using following java pojo for your json which is created using above mentioned tool.

Post.kt

data class Post(
    @PrimaryKey(autoGenerate = true)
    @SerializedName("id")
    val id: Int,

    @SerializedName("title")
    @Embedded
    val title: Title,

    @SerializedName("excerpt")
    @Embedded
    val excerpt: Excerpt,

    @SerializedName("content")
    @Embedded
    val content: Content,

    @SerializedName("date")
    val date: String,

    @SerializedName("modified")
    val modified: String
)

Content.kt

class Content {
    @SerializedName("rendered")
    var content: String? = null
}

Title.kt

class Title {
    @SerializedName("rendered")
    var title: String? = null
}

Excerpt.kt

class Excerpt {
    @SerializedName("rendered")
    var excerpt: String? = null
}

Import following dependency for Gson

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

@SerializedName: Give the ability to map JSON key with java member variable with a different name than JSON key. Check this question

Amolpskamble
  • 863
  • 7
  • 12
  • Hey, it actually helped. But it leads to another problem. Since I have more than one field with `rendered` as sub-key, if naming many @Embedded classes to `rendered`, it will complain about it saying "Multiple fields have the same columnName: rendered". Renaming them differently will not read the value. –  Sep 02 '18 at 16:46
  • Can you please give more details about error and sample json you are trying to parse? – Amolpskamble Sep 02 '18 at 17:17
  • The issue is just like `title: { rendered: "foo" } }`, but there are 2 other keys with `rendered` inside, `content` and `excerpt`, and this causes the error `Error:(8, 8) error: Multiple fields have the same columnName: rendered. Field names: title > rendered, content > rendered, excerpt > rendered.`. I found solutions to append prefixes, but in this case, they were creating their JSON format, in my case, I fetch a format that is already defined, and a different name than `rendered` will not show anything. If you want to see the JSON: http://skillpoint.com.br/wp-json/wp/v2/posts –  Sep 03 '18 at 01:36
  • @gamofe Please check edited answer. Use Gson or any other similar parser if you want to manipulate JSON mapping. Since mapped variables are different from JSON keys, therefore error should go. – Amolpskamble Sep 03 '18 at 07:08
  • Using GSON's `SerializedName` solved it. Just one thing for you to edit in your answer: the name of the variables in the other 3 classes cannot be the same, only the serialized name should be `rendered`. –  Sep 04 '18 at 08:33
  • @gamofe I'm glad this worked out. Can you please edit the answer? – Amolpskamble Sep 04 '18 at 08:38
  • Yes, I just finished doing so. –  Sep 04 '18 at 08:41