0

Good day, I'm using Retrofit for the first time and I can't seem to get it to work. working on an app that get crypto currency rates in local currencies, here is the api [link], JSON format

Here are my models for News

data class News(
@field:SerializedName("totalResults")
val totalResults: Int,
@field:SerializedName("articles")
val articles: List<NewsArticle>?=null,
@field:SerializedName("status")
val status: String)

My model calss for NewsArticles:

data class NewsArticle(

@field:SerializedName("urlToImage")
val urlToImage: String? = null,

@field:SerializedName("description")
val description: String? = null,

@field:SerializedName("title")
val title: String? = null,

@field:SerializedName("url")
val url: String? = null,)

My interface:

const val BASE_URL = "https://saurav.tech/NewsAPI/"
interface NewsApiService {
@GET("top-headlines.json")
fun getNews(
    @Query("category") category: String,
    @Query("country_code") country_code: String
): Call<News>}
object NewsApi{
val newsInstance:NewsApiService
init {
    val retrofit=Retrofit.Builder()
        .baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create())
        .build()
    newsInstance=retrofit.create(NewsApiService::class.java)
 }
   }

My MainActivity class

class MainActivity : AppCompatActivity() {
private lateinit var adapter: NewsAdapter

//var totalResult=1
private var article = mutableListOf<NewsArticle>()
lateinit var refreshLayout: SwipeRefreshLayout
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    recyclerView = findViewById(R.id.recyclerViewNews)
    refreshLayout = findViewById(R.id.refreshLayout)
    adapter = NewsAdapter(this@MainActivity, article)
    recyclerView.adapter = adapter
    recyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
    fetchNews()

}

private fun fetchNews() {
    val news = NewsApi.newsInstance.getNews("technology", "in")
    news.enqueue(object : Callback<News> {
        override fun onResponse(call: Call<News>, response: Response<News>) {

            val news = response.body()
            article.addAll(news!!.articles)
        }

        override fun onFailure(call: Call<News>, t: Throwable) {
            Toast.makeText(applicationContext, t.message, Toast.LENGTH_SHORT).show()
        }

    })
}

}

My AdapterClass:

class NewsAdapter(val context: Context, val newsArticles: MutableList<NewsArticle>) :
RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.news_items, parent, false)
    return NewsViewHolder(view)
}

override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
    val article = newsArticles[position]
    holder.title.text = article.title
    holder.description.text = article.description
    Glide.with(holder.itemView.context).load(article.urlToImage).into(holder.image)
}

override fun getItemCount() = newsArticles.size

class NewsViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    val title = view.findViewById<TextView>(R.id.titleText)!!
    val description = view.findViewById<TextView>(R.id.descriptionText)!!
    val image = view.findViewById<ImageView>(R.id.NewsImage)!!
}

}

When I run the code and check my log I get this error:

java.lang.NullPointerException
    at com.ashish.technews.uis.MainActivity$fetchNews$1.onResponse(MainActivity.kt:44)
    at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
    at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$hVGjmafRi6VitDIrPNdoFizVAdk.run(lambda)
    at android.os.Handler.handleCallback(Handler.java:754)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:165)
    at android.app.ActivityThread.main(ActivityThread.java:6375)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
ahmad bajwa
  • 966
  • 2
  • 10
  • 30

1 Answers1

0

What's Happening?

Article List in the response is not coming and it is not being handled properly.

Solution

Replace this: article.addAll(news!!.articles)

With this: news?.let { article.addAll(it.articles) }

Navjot
  • 1,202
  • 1
  • 11
  • 24