Error onFailure: Expected Begin_Array but was Begin_Object at line 4 column 2 path $

Viewed 16

Android Studio/Kotlin. I'm assuimng the issue is coming from it not being able to convert the json to gson. But I'm not sure if that the case. But based on what I could uncover myself before giving up and asking for help is it might be a error from the rockService. Because I can connent to the network fine and it does retrive the data but still pulls the error message and says it failed. Any help would be appricated

RockService

import com.google.gson.Gson
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

class RockService {
   private val gson by lazy{
       Gson().newBuilder()
   }

   private val loggingInterceptor by lazy{
       HttpLoggingInterceptor().apply {
           level = HttpLoggingInterceptor.Level.BODY
       }
   }

   private val okHttpClient by lazy {
       OkHttpClient.Builder()
           .addInterceptor(loggingInterceptor)
           .connectTimeout(30, TimeUnit.SECONDS)
           .writeTimeout(30,TimeUnit.SECONDS)
           .readTimeout(30,TimeUnit.SECONDS)
           .build()
   }

   val rockAPI: RockAPI by lazy{
       Retrofit.Builder()
           .baseUrl(RockAPI.BASR_URL)
           .addConverterFactory(GsonConverterFactory.create(gson.create()))
           .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
           .client(okHttpClient)
           .build()
           .create(RockAPI::class.java)
   }
}

RockNetworkItem

​​import com.google.gson.annotations.SerializedName

data class RockNetworkItem (
   @SerializedName("Id")
   val artId : Int? = null,
   @SerializedName("NameOfArt")
   val nameOfArt : String? = null,
   @SerializedName("NameOfCollection")
   val nameOfCollection : String? = null,
   @SerializedName("TrackPrice")
   val trackPrice : Double? = null,
   @SerializedName("artworkUrl")
   val artworkUrl60: String ? = null,
)

RockAPI

import io.reactivex.Single
import retrofit2.http.GET

interface RockAPI {

   @GET("search?term=rock&media=music&entity=song&limit=50")
   fun getAllRocks() : Single<List<RockNetworkItem>>

    companion object{
        const val BASR_URL = "https://itunes.apple.com/"
    }
}

RockDomain

import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName

@Entity(tableName = "Rock_Table")
class RockDomain (
   @PrimaryKey
   @SerializedName("artistId")
   val artistId: Int,
   @SerializedName("artistName")
   val artistName: String,
   @SerializedName("collectionName")
   val collectionName: String,
   @SerializedName("trackPrice")
   val trackPrice: Double,
   @SerializedName("artworkUrl60")
   val artworkUrl60: String,
       )


fun List<RockNetworkItem>
       .mapToDomainRockList(): List<RockDomain> =
   this.map {
       RockDomain(
           artistName = it.nameOfArt ?: "",
           collectionName = it.nameOfCollection ?: "",
           trackPrice = (it.trackPrice ?: 999999) as Double,
           artistId = it.artId ?: 999999,
           artworkUrl60 = it.artworkUrl60?: "",
       )
   }

fun RockNetworkItem.mapToDomainRock(): RockDomain =
   RockDomain(
       artistName = this.nameOfArt ?: "",
       collectionName = this.nameOfCollection?: "",
       trackPrice = (this.trackPrice ?: 99999) as Double,
       artistId = this.artId ?: 999999,
       artworkUrl60 = this.artworkUrl60?: ""
   )

RockModel

import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName



data class RockModerl(
   @PrimaryKey (autoGenerate = false)
   @SerializedName("artistId")
   val artistId: Int,
   @SerializedName("artistName")
   val artistName: String,
   @SerializedName("artistViewUrl")
   val artistViewUrl: String,
   @SerializedName("artworkUrl100")
   val artworkUrl100: String,
   @SerializedName("artworkUrl30")
   val artworkUrl30: String,
   @SerializedName("artworkUrl60")
   val artworkUrl60: String,
   @SerializedName("collectionCensoredName")
   val collectionCensoredName: String,
   @SerializedName("collectionExplicitness")
   val collectionExplicitness: String,
   @SerializedName("collectionId")
   val collectionId: Int,
   @SerializedName("collectionName")
   val collectionName: String,
   @SerializedName("collectionPrice")
   val collectionPrice: Double,
   @SerializedName("collectionViewUrl")
   val collectionViewUrl: String,
   @SerializedName("contentAdvisoryRating")
   val contentAdvisoryRating: String,
   @SerializedName("country")
   val country: String,
   @SerializedName("currency")
   val currency: String,
   @SerializedName("discCount")
   val discCount: Int,
   @SerializedName("discNumber")
   val discNumber: Int,
   @SerializedName("isStreamable")
   val isStreamable: Boolean,
   @SerializedName("kind")
   val kind: String,
   @SerializedName("previewUrl")
   val previewUrl: String,
   @SerializedName("primaryGenreName")
   val primaryGenreName: String,
   @SerializedName("releaseDate")
   val releaseDate: String,
   @SerializedName("trackCensoredName")
   val trackCensoredName: String,
   @SerializedName("trackCount")
   val trackCount: Int,
   @SerializedName("trackExplicitness")
   val trackExplicitness: String,
   @SerializedName("trackId")
   val trackId: Int,
   @SerializedName("trackName")
   val trackName: String,
   @SerializedName("trackNumber")
   val trackNumber: Int,
   @SerializedName("trackPrice")
   val trackPrice: Double,
   @SerializedName("trackTimeMillis")
   val trackTimeMillis: Int,
   @SerializedName("trackViewUrl")
   val trackViewUrl: String,
   @SerializedName("wrapperType")
   val wrapperType: String
)

Rockpresenter

import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import com.example.homework3.rockdata.model.RockDomain
import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject


/**
* Rock presenter to for the rock fragment
*/
interface RockPresenter {
   fun init(viewContract: ViewContractRock)
   fun checkNetworkConnection(connectivityManager: ConnectivityManager)
   fun getRock()
   fun destroy()
}

interface ViewContractRock
{
   fun loadingRock(isLoading : Boolean)
   fun onSuccess(rock : List<RockDomain>)
   fun onFailure(error: Throwable)
}

class AllRockPresenterImpl(
   private val rockDAO: RockDAO,
   private val repository : RockReposiory = RockRe(rockDAO),
   private val disposable : CompositeDisposable = CompositeDisposable()
) : RockPresenter
{

   private var contractRock : ViewContractRock? = null


   override fun init(viewContract: ViewContractRock) {
       contractRock = viewContract
   }

   override fun checkNetworkConnection(connectivityManager: ConnectivityManager) {
       connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)?.let {
           if (it.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
               contractRock?.onFailure(Throwable("No"))
           }
       }
   }

   override fun getRock() {

       contractRock?.loadingRock(true)

       repository.getAllRock().subscribe(
           {roccks -> contractRock?.onSuccess(roccks)},
           { error -> contractRock?.onFailure(error)} // This should load from the data base
       ) .also { disposable.add(it) }
   }

   override fun destroy() {
       TODO("Not yet implemented")
   }

}

RockFragment

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.room.Room
import com.example.homework3.databinding.FragmentRockBinding
import com.example.homework3.rockdata.*
import com.example.homework3.rockdata.model.RockDomain
import javax.inject.Inject

class RockFragment : Fragment(),ViewContractRock {

   private val binding by lazy{
       FragmentRockBinding.inflate(layoutInflater)
   }

   private val rockAdapter by lazy{
       RockA()
   }

   //make an adapter and pass value here

   private val rockDB by lazy{
       RockDB.getRockDataBaseIn(requireContext())
   }

   private val presenter by lazy{
       AllRockPresenterImpl(rockDB.Dao())
   }

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)

       presenter.init(this)

   }

   override fun onCreateView(
       inflater: LayoutInflater, container: ViewGroup?,
       savedInstanceState: Bundle?
   ): View? {
       // Inflate the layout for this fragment

       binding.RockRE.apply {
           layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false)
           adapter = RockA()
       }

       presenter.getRock()
       return binding.root
   }

   override fun loadingRock(isLoading: Boolean) {
       Toast.makeText(requireContext(), "Loading", Toast.LENGTH_LONG).show()
       Log.d("Network", "Loading Data")
   }

   override fun onSuccess(rock: List<RockDomain>) {
       //rockAdapter.
       //Use adapater to change view to add the data
       rockAdapter.updateRock(rock)
       Toast.makeText(requireContext(), "Success", Toast.LENGTH_LONG).show()
       Log.d("Network", "Data has loaded")
   }

   override fun onFailure(error: Throwable) {
       Log.e("Network", "onFailure: ${error.localizedMessage}", error)
       Toast.makeText(requireContext(), "Failed", Toast.LENGTH_LONG).show()
   }
}
0 Answers
Related