Home > Enterprise >  How to return a Result<Unit> from fetch and save database operation
How to return a Result<Unit> from fetch and save database operation

Time:09-09

Scenario

I have a function add()which fetches data from remoteDataSource and, if successful, saves it it to localDataSource.

When I try to return the result I am getting error Type mismatch. Required: Result<Unit> Found: Result<Foo>.

I believe this is because remoteDataSource.fetch() is returning Result<Foo> and not my nested Result.success/failure()

How can I get add() to return the nested Result<Unit>?

Note I am using the Kotlin Return type.

suspend fun add(csv: String): Result<Unit> {
    return try {
        remoteDataSource.fetch(csv) /*<---remoteDataSource.fetch() returns Result<Foo>*/
            .onSuccess { result ->
                localDataSource.save(result) /*<---localDataSource.save() returns Result<Unit>*/
                    .onSuccess {
                        Result.success(Unit)
                    }
                    .onFailure {
                        Result.failure<Unit>(Throwable(it))
                    }
            }
            .onFailure {
                Result.failure<Unit>(Throwable(it))
            }
    } catch (e: Exception) {
        e.printStackTrace()
        Result.failure(e)
    }
}

Update

I have discovered the fold() function which is able to transform the result returned by onSuccess{...}. However I am not sure if this is correctly capturing throwables in both remoteDataSource and LocalDataSource. Please confirm if this is a viable solution or if another approach should be used.

override suspend fun add(csv: String): Result<Unit> {
    return try {
        remoteDataSource.fetch(csv)
            .onSuccess { result ->
                localDataSource.save(result)
            }.fold(
                onSuccess = { Result.success(Unit) },
                onFailure = { Result.failure(Throwable()) }
            )
    } catch (e: Exception) {
        e.printStackTrace()
        Result.failure(e)
    }
}

CodePudding user response:

The methods onSuccess and onFailure are callbacks, so you are not returning Result at all but returning whatever onFailure is returning, probably Void.

Please make sure your interface is making the request with a suspend method and is returning a Response.

Then you can do like this:

suspend fun add(csv: String): Result<Unit> {
    return try {
        val response = remoteDataSource.fetch(csv)
        if (response.isSuccesfull) {
             localDataSource.save(response.body)
             Result.success(Unit)
        } else Result.failure(RunTimeException("${response.code}"))
    } catch (e: Exception) {
        e.printStackTrace()
        Result.failure(e)
    }
}

CodePudding user response:

From the documentation, the Unit is equal to void. So it throws as an error in this part if you want it as Generic POJO you have to mention it as <T> instead of <Unit>

For Common, JVM, JS The type with only one value: the Unit object. This type corresponds to the void type in Java.

  • Related