From d45812c2de98da5ac0e3a716a695aa83c146c6d7 Mon Sep 17 00:00:00 2001 From: Daniel Stone <me@danstone.uk> Date: Wed, 15 Jul 2020 10:19:10 +0100 Subject: [PATCH 1/3] Improve error handling code to match master branch --- .../toc/ui/chapters/ChaptersViewModel.kt | 17 ++++------- .../toc/ui/sections/SectionsViewModel.kt | 28 ++++++++----------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt b/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt index ffdd746..8fbf50a 100644 --- a/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt +++ b/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt @@ -1,6 +1,5 @@ package guide.graphql.toc.ui.chapters -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.liveData @@ -20,19 +19,15 @@ class ChaptersViewModel : ViewModel() { ).toDeferred().await() if (response.hasErrors()) { - emit(Resource.error("Response has errors", null)) - return@liveData + throw Exception("Response has errors") } - response.data?.chapters?.let { - emit(Resource.success(response.data!!.chapters)) - return@liveData - } - emit(Resource.error("Data is null", null)) - return@liveData + + val chapters = response.data?.chapters ?: throw Exception("Data is null") + emit(Resource.success(chapters)) } catch (e: ApolloException) { - Log.d("ChaptersQuery", "GraphQL request failed", e) emit(Resource.error("GraphQL request failed", null)) - return@liveData + } catch (e: Exception) { + emit(Resource.error(e.message.orEmpty(), null)) } } } \ No newline at end of file diff --git a/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt b/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt index 68d5d63..d54b309 100644 --- a/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt +++ b/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt @@ -1,11 +1,10 @@ package guide.graphql.toc.ui.sections -import android.util.Log import androidx.lifecycle.* import com.apollographql.apollo.coroutines.toDeferred import com.apollographql.apollo.exception.ApolloException -import guide.graphql.toc.data.Resource import guide.graphql.toc.SectionsQuery +import guide.graphql.toc.data.Resource import guide.graphql.toc.data.apolloClient class SectionsViewModel : ViewModel() { @@ -23,32 +22,27 @@ class SectionsViewModel : ViewModel() { } val sectionsList: LiveData<Resource<List<SectionsQuery.Section?>>> = - _chapterId.switchMap { sectionId -> + _chapterId.switchMap { chapterId -> return@switchMap liveData { emit(Resource.loading(null)) try { val response = apolloClient.query( - SectionsQuery(id = sectionId) + SectionsQuery(id = chapterId) ).toDeferred().await() if (response.hasErrors()) { - emit(Resource.error("Response has errors", null)) - return@liveData + throw Exception("Response has errors") } - response.data?.chapter?.sections?.let { sections -> - if (sections.size > 1) { - emit(Resource.success(sections)) - } else { - emit(Resource.error("No sections", null)) - } - return@liveData + val sections = response.data?.chapter?.sections ?: throw Exception("Data is null") + if (sections.size > 1) { + emit(Resource.success(sections)) + } else { + throw Exception("No sections") } - emit(Resource.error("Chapter has no sections", null)) - return@liveData } catch (e: ApolloException) { - Log.d("Sections Query", "GraphQL request failed", e) emit(Resource.error("GraphQL request failed", null)) - return@liveData + } catch (e: Exception) { + emit(Resource.error(e.message.orEmpty(), null)) } } } From d1c0c5f16e62dd72c686a5a1db7992cd2d968405 Mon Sep 17 00:00:00 2001 From: Daniel Stone <me@danstone.uk> Date: Fri, 17 Jul 2020 10:17:28 +0100 Subject: [PATCH 2/3] Update View Binding --- .../graphql/toc/ui/chapters/ChaptersFragment.kt | 13 +++++++++++-- .../graphql/toc/ui/sections/SectionsFragment.kt | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersFragment.kt b/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersFragment.kt index eba69f0..bf1aeb3 100644 --- a/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersFragment.kt +++ b/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersFragment.kt @@ -17,17 +17,21 @@ import guide.graphql.toc.data.Status import guide.graphql.toc.databinding.ChaptersFragmentBinding class ChaptersFragment : Fragment() { + private var _binding: ChaptersFragmentBinding? = null + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + private val viewModel: ChaptersViewModel by viewModels() - private lateinit var binding: ChaptersFragmentBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - binding = ChaptersFragmentBinding.inflate(inflater) + _binding = ChaptersFragmentBinding.inflate(inflater, container, false) return binding.root } @@ -86,4 +90,9 @@ class ChaptersFragment : Fragment() { } }) } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } \ No newline at end of file diff --git a/app/src/main/java/guide/graphql/toc/ui/sections/SectionsFragment.kt b/app/src/main/java/guide/graphql/toc/ui/sections/SectionsFragment.kt index 34b2bf8..29cd1d4 100644 --- a/app/src/main/java/guide/graphql/toc/ui/sections/SectionsFragment.kt +++ b/app/src/main/java/guide/graphql/toc/ui/sections/SectionsFragment.kt @@ -18,7 +18,12 @@ class SectionsFragment : Fragment() { private val viewModel: SectionsViewModel by viewModels() - private lateinit var binding: SectionsFragmentBinding + private var _binding: SectionsFragmentBinding? = null + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + private val args: SectionsFragmentArgs by navArgs() override fun onCreateView( @@ -26,7 +31,7 @@ class SectionsFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - binding = SectionsFragmentBinding.inflate(inflater) + _binding = SectionsFragmentBinding.inflate(inflater, container, false) return binding.root } @@ -78,6 +83,11 @@ class SectionsFragment : Fragment() { viewModel.chapterId = args.chapterId } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + private fun showErrorMessage(error: String) { binding.spinner.visibility = View.GONE binding.error.text = error From eb603af8a372e7eff430f108899ed5034e0e58fb Mon Sep 17 00:00:00 2001 From: Daniel Stone <me@danstone.uk> Date: Mon, 3 Aug 2020 21:15:54 +0100 Subject: [PATCH 3/3] Use Kotlin object keyword for apollo client --- .../main/java/guide/graphql/toc/data/Apollo.kt | 18 ++++++++++++------ .../toc/ui/chapters/ChaptersViewModel.kt | 4 ++-- .../toc/ui/sections/SectionsViewModel.kt | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/guide/graphql/toc/data/Apollo.kt b/app/src/main/java/guide/graphql/toc/data/Apollo.kt index e12866c..cb8ddfc 100644 --- a/app/src/main/java/guide/graphql/toc/data/Apollo.kt +++ b/app/src/main/java/guide/graphql/toc/data/Apollo.kt @@ -4,10 +4,16 @@ import com.apollographql.apollo.ApolloClient import com.apollographql.apollo.cache.normalized.lru.EvictionPolicy import com.apollographql.apollo.cache.normalized.lru.LruNormalizedCacheFactory -val cacheFactory = - LruNormalizedCacheFactory(EvictionPolicy.builder().maxSizeBytes(10 * 1024 * 1024).build()) +object Apollo { -val apolloClient: ApolloClient = ApolloClient.builder() - .serverUrl("https://api.graphql.guide/graphql") - .normalizedCache(cacheFactory) - .build() \ No newline at end of file + val client: ApolloClient by lazy { + val cacheFactory = + LruNormalizedCacheFactory(EvictionPolicy.builder().maxSizeBytes(10 * 1024 * 1024).build()) + + ApolloClient.builder() + .serverUrl("https://api.graphql.guide/graphql") + .normalizedCache(cacheFactory) + .build() + } + +} \ No newline at end of file diff --git a/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt b/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt index 8fbf50a..3a59b63 100644 --- a/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt +++ b/app/src/main/java/guide/graphql/toc/ui/chapters/ChaptersViewModel.kt @@ -6,15 +6,15 @@ import androidx.lifecycle.liveData import com.apollographql.apollo.coroutines.toDeferred import com.apollographql.apollo.exception.ApolloException import guide.graphql.toc.ChaptersQuery +import guide.graphql.toc.data.Apollo import guide.graphql.toc.data.Resource -import guide.graphql.toc.data.apolloClient class ChaptersViewModel : ViewModel() { val chapterList: LiveData<Resource<List<ChaptersQuery.Chapter>>> = liveData { emit(Resource.loading(null)) try { - val response = apolloClient.query( + val response = Apollo.client.query( ChaptersQuery() ).toDeferred().await() diff --git a/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt b/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt index d54b309..7b9181a 100644 --- a/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt +++ b/app/src/main/java/guide/graphql/toc/ui/sections/SectionsViewModel.kt @@ -4,8 +4,8 @@ import androidx.lifecycle.* import com.apollographql.apollo.coroutines.toDeferred import com.apollographql.apollo.exception.ApolloException import guide.graphql.toc.SectionsQuery +import guide.graphql.toc.data.Apollo import guide.graphql.toc.data.Resource -import guide.graphql.toc.data.apolloClient class SectionsViewModel : ViewModel() { @@ -26,7 +26,7 @@ class SectionsViewModel : ViewModel() { return@switchMap liveData { emit(Resource.loading(null)) try { - val response = apolloClient.query( + val response = Apollo.client.query( SectionsQuery(id = chapterId) ).toDeferred().await()