DEV Community

LiHan
LiHan

Posted on • Edited on

1

[Android] UserListApp - Data Part - Part3

Remote Info

https://random-data-api.com/documentation

Response Data is

Data Type

Create UserDto

Not create all data type .

data class UserDto(
    val id : Int ,
    val username : String ,
    val gender : String ,
    val phone_number : String ,
    val date_of_birth : String,
    val email : String,
    val avatar : String,
    val address: Address,
)

Enter fullscreen mode Exit fullscreen mode
data class Address(
    val city: String,
    val coordinates: Coordinates,
    val country: String,
    val state: String,
    val street_address: String,
    val street_name: String,
    val zip_code: String
)
data class Coordinates(
    val lat: Double,
    val lng: Double
)

Enter fullscreen mode Exit fullscreen mode

Create Remote API Interface UserApi

interface UserApi {

    @GET("users")
    suspend fun getRandomUser() : Response<UserDto>

    @GET("users")
    suspend fun getUserBySize(
        @Query("size") size : String,
    ) : Response<List<UserDto>>

    companion object{
        const val BASE_URL = "https://random-data-api.com/api/v2/"
    }

}
Enter fullscreen mode Exit fullscreen mode

Create Mapper

fun UserDto.toUser() : User {
    return User(
        id= id,
        username = username,
        gender = gender,
        phoneNumber = phone_number,
        dateOfBirth = date_of_birth,
        email = email,
        avatar = avatar,
        lat = address.coordinates.lat,
        lng = address.coordinates.lng
    )
}
Enter fullscreen mode Exit fullscreen mode

Create Custom Result Class Resource.kt

sealed class Resource<T>(val data : T?=null , val message : String ?=null){
    class Loading<T>(data: T? = null) : Resource<T>(data)
    class Error<T>(data: T? = null , message: String?) : Resource<T>(data,message)
    class Success<T>(data: T?) : Resource<T>(data)
}
Enter fullscreen mode Exit fullscreen mode

Create Domain Repository UserRepository

這個UserRepository裡面的資料一定是User,因為要在App內使用的
所以在實作那層會有一個Mapper去做轉換(domain>util>UserMapper.kt)

interface UserRepository {

    suspend fun getRandomUser(): Flow<Resource<User>>

    suspend fun getUserBySize(size : String) : Flow<Resource<List<User>>>
}
Enter fullscreen mode Exit fullscreen mode

Create Data Repository UserRepositoryImpl

class UserRepositoryImpl(
    private val userApi: UserApi
) : UserRepository{

    override suspend fun getRandomUser(): Flow<Resource<User>> = flow{
       emit(Resource.Loading())
        try {
            val result = userApi.getRandomUser()
            if (result.isSuccessful){
                result.body()?.let {
                    emit(
                        Resource.Success(it.toUser())
                    )
                }
            }else{
                emit(
                    Resource.Error(
                        data = null,
                        message = "${result.errorBody()?.string()}"
                    )
                )
            }
        }catch (e : IOException){
            emit(
                Resource.Error(
                    data = null,
                    message = "IOE Error"
                )
            )
        }

    }

    override suspend fun getUserBySize(size: String): Flow<Resource<List<User>>> = flow{
        emit(
            Resource.Loading()
        )
        try {
            val result = userApi.getUserBySize(size)
            if (result.isSuccessful){
                result.body()?.let {
                    it.let {
                        emit(
                            Resource.Success(
                                data =it.map { userDto ->
                                    userDto.toUser()
                                }
                            )
                        )
                    }
                }
            }else{
                emit(
                    Resource.Error(
                        data = emptyList(),
                        message = result.errorBody()?.string()
                    )
                )
            }
        }catch (e : IOException){
            emit(
                Resource.Error(
                    data = null,
                    message = e.message
                )
            )
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

AWS GenAI Live!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️