0

I am pulling a word json file data from my asset file. then I try to save these data in my room database. I 'm gonna read these data from room after I save. this is my plan but I have a error.

I will share my error and codes below

This json file looks like this

My word json file in asset folder

[
  {
    "words": [
      {
        "word": "the",
        "meaning": " “The sky is blue.” "
      },
      {
        "word": "be",
        "meaning": "be – “Will you be my friend?”"
      },
      {
        "word": "and",
        "meaning": "and – “You and I will always be friends.”"
      },
      {
        "word": "of",
        "meaning": "of – “Today is the first of November.”"
      },

ERROR

and I get the following error while processing it.

 kotlinx.serialization.MissingFieldException: Field 'words' is required for type with serial name 'com.enestigli.dictionaryapp.data.locale.datamodel.WordsItem', but it was missing
        at kotlinx.serialization.internal.PluginExceptionsKt.throwMissingFieldException(PluginExceptions.kt:20)
        at com.enestigli.dictionaryapp.data.locale.datamodel.WordsItem.<init>(Word.kt:19)
        at com.enestigli.dictionaryapp.data.locale.datamodel.WordsItem$$serializer.deserialize(Word.kt:19)
        at com.enestigli.dictionaryapp.data.locale.datamodel.WordsItem$$serializer.deserialize(Word.kt:19)
        at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59)
        at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36)
        at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
        at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
        at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:535)
        at kotlinx.serialization.internal.ListLikeSerializer.readElement(CollectionSerializers.kt:80)
        at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
        at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
        at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
        at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59)
        at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36)
        at com.enestigli.dictionaryapp.data.locale.datamodel.WordDataModel$$serializer.deserialize-hOmtatA(Word.kt:11)
        at com.enestigli.dictionaryapp.data.locale.datamodel.WordDataModel$$serializer.deserialize(Word.kt:11)
        at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59)
        at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36)
        at kotlinx.serialization.json.Json.decodeFromString(Json.kt:100)
        at com.enestigli.dictionaryapp.data.locale.datasource.AssetDataSource.getCommonWords-hOmtatA(AssetsDataSource.kt:109)
        at com.enestigli.dictionaryapp.data.repository.WordRepositoryImpl.initData(WordRepositoryImpl.kt:24)
        at com.enestigli.dictionaryapp.domain.use_case.commonword.insert.InsertCommonWordUseCase.insertCommonWord(InsertCommonWordUseCase.kt:13)
        at com.enestigli.dictionaryapp.presentation.SplashScreen.SplashScreenViewModel$insertAllDataToRoomDb$1.invokeSuspend(SplashScreenViewModel.kt:41)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7898)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
        Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@c7efc65, Dispatchers.Main.immediate]

my data model for word

@JvmInline
@Serializable
value class WordDataModel(
    val allData : List<WordsItem>
)



@Serializable
data class WordsItem(
    val words: List<CommonWords>
) {
    fun toEntity() = CommonWordEntity(
        words = words
    )

}

@Serializable
data class CommonWords(
   val word:String,
   val meaning:String
)

Room

Entity

@Entity(tableName = "MostCommonWords")
data class CommonWordEntity(


    @ColumnInfo(name = "commonWord") val words : List<CommonWords>,
    @PrimaryKey(autoGenerate = true) val uid : Int? = null

)

Dao

@Dao
interface CommonWordDao {

    @Query("SELECT * FROM MostCommonWords")
    suspend fun getAllWords() : List<CommonWordEntity>


    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun initData(word : List<CommonWordEntity> )

}

Database

@Database(
    entities = [CommonWordEntity::class],
    version = 1
)

@TypeConverters(CommonWordConverter::class)
abstract class CommonWordDatabase: RoomDatabase() {
    abstract val wordDao: CommonWordDao

}

Repositories

WordRepositoryImpl

class WordRepositoryImpl @Inject constructor(
    private val dao: CommonWordDao,
    private val assetDataSource: AssetDataSource
) : WordRepository {


    override suspend fun initData() {

        val wordsList = assetDataSource.getCommonWords().allData
        dao.initData(wordsList.map{it.toEntity()})

    }

   override suspend fun getAllWords() : Flow<List<CommonWords>?> {

        return flow {
            emit(dao.getAllWords().map { it.words}.flatten())
        }

    }


}

WordRepository

interface WordRepository {

    suspend fun initData()
    suspend fun getAllWords() : Flow<List<CommonWords>?>


}  

Use cases

getall

class GetAllCommonWordUseCase @Inject constructor(
    private val repository: WordRepository
){

    suspend fun getAllCommonWord() : Flow<List<CommonWords>?> {

        return repository.getAllWords()
    }
}

insert room

class InsertCommonWordUseCase @Inject constructor(
    private val repository: WordRepository
) {
    suspend fun insertCommonWord() {

        repository.initData()
    }
}

I think everything is correct but I think my data model may not be quite correct, based on the error because the error is caused by words. There seems to be no mistake between the naming in the json file and the naming in my data model. Unfortunately I couldn't find the problem. What can be the problem ?

EDIT

Normal json file

[
      {
        "word": "the",
        "meaning": " “The sky is blue.” "
      },
      {
        "word": "be",
        "meaning": "be – “Will you be my friend?”"
      },
      {
        "word": "and",
        "meaning": "and – “You and I will always be friends.”"
      },
      {
        "word": "of",
        "meaning": "of – “Today is the first of November.”"
      },
      {
        "word": "a",
        "meaning": "a – “I saw a bear today.”"
      },
      {
        "word": "in",
        "meaning": "in – “She is in her room.”"
      },
      {
        "word": "to",
        "meaning": "to – “Let’s go to the park.”"
      },
      {
        "word": "have",
        "meaning": "have – “I have a few questions.”"
      },
      {
        "word": "too",
        "meaning": "too – “I like her too.”"
      },
      {
        "word": "it",
        "meaning": "it – “It is sunny outside.”"
      },
      {
        "word": "I",
        "meaning": "I – “I really like it here.”"
      },
      {
        "word": "that",
        "meaning": "that – “That door is open.”"
      },
      {
        "word": "for",
        "meaning": "for – “This letter is for you.”"
      },
      {
        "word": "you",
        "meaning": "you – “You are really nice.”"
      },

it continues like this. Accordingly, how can I edit my codes or how can I fix the problem?

THE ERROR IS SOLVED

The solution for the error was caused by me. Since normally that json file doesn't have this data. I changed the name of the json file with the correct json file and the problem was solved. it was my mistake. Thank you for your answers.

NewPartizal
  • 604
  • 4
  • 18

1 Answers1

1

Looks that some of the items in your JSON doesn't contain the words field and since you don't accept the val words: List<CommonWords> to be null - you get the exception.

To confirm that, try making it nullable and then check if you still get the exception.

Mieczkoni
  • 505
  • 2
  • 8
  • in this case How should I create a data model ? if I accept null data for words it wont work properly I think. – NewPartizal Nov 28 '22 at 11:10
  • We'd have to see the whole JSON, could you provide it? – Mieczkoni Nov 28 '22 at 11:26
  • There's a lot of data so it's a little hard to put in here. We can think of it as a continuation of the json file I added above.There is only one list of words and there are words and meanings in it, actually I added words list manuelly. I had prepared my data model as above, but there was no list called words. When I encountered such a problem, I added it manually, maybe it would work, but it didn't. I will share the normal json file as an attachment above. – NewPartizal Nov 28 '22 at 11:40
  • By the way if I accept val words:List to be null. I got a error flatten in repositoryImpl. The error is Function invocation 'flatten(...)' expected – NewPartizal Nov 28 '22 at 12:16
  • I'm so sorry it was my fault. I wrote wrong json file name when I read data from json file. the error is caused by. I 'm so sorry again. By the way your answer is correct @Mieczkoni thanks for your answer. – NewPartizal Nov 28 '22 at 13:00