Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start coroutines migration of KSApolloClientV2.getStoredCards() #2223

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

tonyteate
Copy link
Contributor

Do not merge ❌

πŸ“² What

Start coroutines migration of KSApolloClientV2.getStoredCards()

  • Update PaymentMethodsViewModel + Tests
  • Update LatePledgeCheckoutViewModel + Tests

πŸ€” Why

Some background context on why the change is needed.

πŸ›  How

More in-depth discussion of the change or implementation.

πŸ‘€ See

Trello, screenshots, external resources?

Before πŸ› After πŸ¦‹

πŸ“‹ QA

Instructions for anyone to be able to QA this work.

Story πŸ“–

[Name of Trello Story](Trello link)

- Update PaymentMethodsViewModel + Tests
- Update LatePledgeCheckoutViewModel + Tests
@codecov-commenter
Copy link

codecov-commenter commented Feb 11, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 84.74576% with 9 lines in your changes missing coverage. Please review.

Project coverage is 68.14%. Comparing base (dc88440) to head (37d4a79).
Report is 16 commits behind head on master.

Files with missing lines Patch % Lines
.../kickstarter/viewmodels/PaymentMethodsViewModel.kt 86.11% 3 Missing and 2 partials ⚠️
...wmodels/projectpage/LatePledgeCheckoutViewModel.kt 82.60% 2 Missing and 2 partials ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #2223      +/-   ##
============================================
+ Coverage     68.11%   68.14%   +0.02%     
+ Complexity     2191     2188       -3     
============================================
  Files           354      354              
  Lines         23881    23904      +23     
  Branches       3505     3510       +5     
============================================
+ Hits          16267    16289      +22     
- Misses         5771     5773       +2     
+ Partials       1843     1842       -1     

β˜” View full report in Codecov by Sentry.
πŸ“’ Have feedback on the report? Share it here.

@@ -232,6 +237,9 @@ class KSApolloClientV2(val service: ApolloClient, val gson: Gson) : ApolloClient
disposables.clear()
}

private fun <T : Any> emitAsObservable(block: suspend () -> T): Observable<T> =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’– , elegant!

Pair(userPrivacy, cards)
}
@OptIn(FlowPreview::class)
val user = currentUser.timeout(1.seconds).runCatching { first() }.getOrNull()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the timeout?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When there is no logged in user, environment.currentUserV2()?.loggedInUser() does not emit, which leaves a Collector suspended forever.

In tests, this is not as clear when running on backgroundScope since the scope cancels at the end of the test. In production, if we want to try to get the user, and fail if there isn't one, we need the timeout. Otherwise, if we want to collect forever intentionally, we should launch a separate coroutine earlier in the business logic.

This currently appears to not be a bug in production because we check for a logged in user before we call providePledgeData().

Copy link
Contributor

@Arkariang Arkariang Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternative path to the timeout, can change from environment.currentUserV2()?.loggedInUser() over toenvironment.currentUser.observable() it will operate with a KSOptional<User?>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's perfect πŸ‘ I tried to stay close to the original in case I missed something. Thanks!

.build()
} ?: listOf()
} catch (apolloException: ApolloException) {
// parse network errors into specific type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to provide some feedback to the user. For example a pretty used pattern now within the app is displaying a red snackbar on the UI, usually with a generic message "something went wrong if no message provided on the API". It was achieved before with the doOnError block.
We could add some kind of callback the consumer of _getStoredCards() to still be able to provide feedback to the user when a error happens.

[email protected](it)
}
.onFailure {
[email protected](false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ‘

var ret = listOf<StoredCard>()
try {
// `single()` vs `singleOrNull()`
val response = this.service.query(query).toFlow().single()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be changed over val response = this.service.query(query).execute() it internally uses toFlow().single()

this.refreshCards
.switchMap { getListOfStoredCards() }
.subscribe { this.cards.onNext(it) }
this.refreshCards.subscribe {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question here, I assume this piece is for demonstration purposes, because this piece over here be just exchanging within the switch map getListOfStoredCards() over apolloClient.getStoredCards(), let me know if I'm missing something!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants