MVVM Movies App - Data Layer: Retrofit & Room DB - (Part 1)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello welcome everyone to my very first playlist in this channel in which we'll be building this movies app uh this first offline movies app actually so this is how it looks like we have a bunch of movies basically this section for popular movies and here we have the upcoming movies when we click on a movie we get to see some data the rating the language and the dat votes the title some images and the overview and the cool part about this app is that let's for example get to the bottom we keep actually pting and loading new movies as we scroll and then when of course there is no image then we'll display this and just like this when there is no data we display zeros so uh if we turn off internet connection or play mode like this and then we open the app we can still get the movies as you can see so this is the first offline app that actually works on offline mode because all this data is actually cached in the user device so you will see how you can make API calls get the data from the API and then cach that data with room database and then get the data from room database so basically whatever you see here is actually accessed from I mean we access it from uh our device but actually exist in room database so everything we accessing is in room database and uh yes so this is the app as I said you will see a lot of things like how to use view models screens and create these gradients and get the average color from an image and uh yes all of these and the API we'll be using for this uh app is this API the movies database I guess the movies DB API uh you can just come to this website I will link it create an account normally just Cas an account with your uh data and then go to settings and go to API right here you will find an API key I'm not going to click right here because I don't want you to see my API key but uh in fact let me just click I will hide it and uh this is the API key just copy the API key that's all you need just copy and keep it somewhere just like it's e here now this is the API key and when you go to the documentation of the of the of this uh API developer. the.org this is the documentation we want we are in fact there are a lot of things you can actually get with this API but for the Simplicity of this video and then actually when you do this you can extend this as you want we will uh where is that I actually just lost it we want uh this popular and upcoming movies you can use of course the same not line just it's just a a query that changes or in fact a path that changes you can CH you can choose any of these so in popular movies this is the the URL uh let's now try it so we'll load in the first page and here are now the movies as you can see let me just scroll like this these are the movies and then in the upcoming movies it's the same URL but we actually just changed the path and when we click try it yes but actually if we put this URL directly uh it won't work because we need an API key for that so uh this is now how actually it will work uh if we have our URL like this and then we say upcoming movies and then we specified language for example here we specified English and uh the page we want and then the Epi key I'm not going to show the rest of it so yeah so the this one is the path and then language is a query page is a query so we can have different pages one 2 three of course and then the apepi key is another query so let's increase the page into two we get new movies basically and then right here if we change the just into popular now we get the popular movies so this is the URL that we are going to use in our app to get the movies and don't forget to check my Instagram account and follow me there I post uh under and general programming uh tips and uh content I will link this account on the description of course you will find this app uh the source code of this app on the description it will be on GitHub so actually this is the type of videos that you need to watch if you want to re learn Android because in the previous videos all I did is introduced you to some technologies like dger Hil retrofit and the navigation and all these stuff but can you actually put all these things together in a functioning solid app that's the thing this is a clean architecture app basically that uses mvvm design pattern and this is the app that you need to watch I mean the video that you need to watch to build an app to to build a clean architecture solid app so you see how you can use retrofit room database and cach all that data get it uh use cortines uh flows channels and all these things in one app basically so what do we need for this app first the dependencies of course in our build. Gradle we need the navigation because we navigate between uh different screens as you can see we have the actually home screen and then inside that home screen we have this bottom navigation which again has two screens the popular movies and the upcoming movies uh screen and then we have the details screen so we have actually four screens in our app and then we need room database to catch the data we need dager health for dependency insection I actually explained this in the previous video you can go back and check it out if you don't know what d health and dependency injection is I also explained room database and I also actually explained navigation in compose and we need Ro it this is how we can get the movies from the API and I also made a video a detailed video about this we need Quail to load images Quail is just like Glide from XML if you have used uh Glide before this is the alternative to that in jitb compose extended icons to get like uh more icons to use and system UI controller just to change the this statu bar color because it it's color by default is the primary color and it looks bad but this is better I make it the same as this color right right here so these are the dependencies we need and uh right here we need this plugin the darker Hil plugin and this SC as well because uh dger health uses annotations and generates Sid behind the scenes and we need that for dger health and also this plugin in our uh project up uh gr fire just paste now these you can find as I said this in the description and then you can go good to go so what do we need to create first the packages actually the first package is of course for uh the movies list in which uh we'll have uh the different things the data layer domain and the view model everything inside there so let's create now the first package I'm just going to call it movie list uh list like this and inside here we first start with the data layer which is actually the most complex uh ler maybe so data and inside our data we need different things we need a local uh package to handle all the local operations with room database and uh inside again the data layer we need another we need another layer for remote to handle all I guess I need to rename this to handle all the API calls and stuff that has to do with the API inside this room inside this package I mean and we need uh the repository package but let's first just start with the remote and inside our remote we're going to create now an API uh I I said I explained this explain this you can go back if you don't know what I'm doing but an API is just an interface so I'm going to call it movie API uh in fact it's not a class it's an interface as I said and inside our API uh let's just actually bring this a little bit like this inside our API will have one function which is a suspend fun get movies list to get all the list of movies basically and we'll annotate this with get from retrofit and then uh first of all let's just create the base URL inside a companion object we'll have a con Val base URL that is equal I'm just going to actually paste it so this is the base URL we'll duplicate this for actually the image because uh this is how we can get the image from the database because actually uh from let's just go back to the API I don't know if I can see this but I don't think I can find it anyway I actually go to the website it which is uh Json editor I guess I think we'll have a better view right there so this is how the API actually would look like and uh let's search for the image here as you can see here is the first image and uh the second image we just get like the ID you could say of the image and then like it's gpg or something but the rest of the URL is actually this that I'm going to paste so this is or the base of that URL you could say this is it and then the API key so API key but I'm not actually going to write it just remove this because I don't want you to see my API key obviously uh so what do we need after the base URL to load the uh movies first of all we need to specify let's go back to to the URL right here we need to specify the first path which is movie so just write movie and then put a slash the second path we want actually is changeable so it could be popular or upcoming so this one is mut is mutable we could say so we'll name it category of the movie so category and uh this is it for the paths now the rest of the things will be just quaries so from the language in fact we don't actually need to specify language I guess uh we just need the page and the API key we don't need language actually to get like different language movies uh so the first path we need so just annotate now this path with path and uh uh category that's s where we want to name it so category and that is category of type string think that's now the actually only path we have and then the rest of the thing is just queries we have two queries the first one is the page because as I showed you you can increase the page to get more movies so the page pages of type integer and the last query is the Epi key so Epi key just like this uh that is a API key and is of type string and by default it is just API key so we don't actually pass it yes I guess I can do this like this uh yes this is it now for our uh what do we call this API this is it for this API we can get movies with this API now the second thing in our remote is that we want to have a respond package so what uh we'll get in actually from the API so respond and inside here I'm not actually going to manually create anything but we'll use this plugin that you can get of course from plugins these plugins actually just generate data classes for our API so here you go to plugin and just search Json in the marketplace just Json and you'll get it install and then install it you may need to restart the IDE to be able to use it so how does this plugin work so if we go here to our API just copy the entire thing again I already explained this in the retrofit video go to respond new cotland data class from Json we paste now our Json and let's name it uh movie list dto so d dto stands for data access objects so this is how we access the objects you could say inside our dto this is how it looks like because in our API we have actually paged even if you didn't see that but if we go all oops what did I do what did I do all the way down I don't know what's going on is it all the way down yes you can see to top pages results and at the top we have uh the number of page and then the list of movies so page movies that is called results in results in this case total Pages total results and now this is now our movie which is called the result in this case which we have all the data like um ID and title I don't know everything we need overview and uh actually I'm not going to call it result I'm going to name it to have a more uh descriptive name which is movie dto and I'm not renaming it here because if if you re if you rename this then actually this library that generates this data class wouldn't know what that is if if it's not called results because in the API it is called results so it wouldn't know what this is and it might just throw an error or something but it wouldn't work so keep naming it results because that's the name of it in the API now actually in our movie dto these are knowable because sometimes you happen to get a movie that has no language or no overview actually in inside it so these are knowable I'm just going to uh put question marks like this to make them n but there's no point of doing that I'm just going to actually paste that so all of these like this all of them put a little question mark there to tell that these are nullable so they can be null uh so yes but these actually can't be null these are always available now what's next actually this is it for our remote uh we can already get movies like this with this API uh I'm going now to create my database so inside my local package I'm going to create uh I could call it me if you want to have more than one package because uh if you want to extend this app then you might want to show the Genies of the movies then you need a different database for for that because you can get that from you can set different API because you need to change the entire Ur not the entire URL but what comes after the base URL will be completely different so you may need a different URL to save those I mean different database to save those as I did actually in the original app I'm just going to show it to you so this is the original app I am not going to make this app look like this because this one is way too complex and it will take forever to build that but if we scroll here and we'll find actually we get the genery of the movie which is in this case comedy and also here Drama action and adventure and all these stuff but to get this you actually need to change the url what comes after the B and also to get the length of the movie and this thing I don't know you know with some uh introduction to the movie or something like this you need to change the base URL and not the base URL but what comes after that so you may need to create uh a different API and different database for that but for our case I'm not going to do that just keep this simple but that's actually will be your homework when you make this you watch me make this and you get it done your homework is actually to extend send the app and make it look like this because this is a more advanced app more beautiful or has more features you can actually watch a tutorial I mean a trailer which you actually need to make a different API car for that uh so you can extend this and everything is available here every single thing you need for movies and TV series actually as well is available here so just you can do that and you can also get the cast or the actors in each movie so in our local uh package I'm going to have a package called movie I guess because as I said you can create different databases for this movie Just For the Movies database in which I will have uh first of all the da which is oh I made a mistake actually this one is not what is that this one is not data access object so this one is not data access object but data trans Fair object because with this we can get the data and then transfer it to entities basically uh that we can store in our database I just made that mistake this is data transfer object remember that and the one we're going to create right now so I'm going to call it movie start out with a capital letter movie D Dow this is now the data access object so with this interface we can now access the objects inside our room database so what do we need actually we need to annotate this with Dow like this and we'll have three functions here the first one is going to be an upsert function which is a suspend fun uh upsert movies list or movie list and that will take the list list of the movies so movie list that is of type uh actually I did not create the entity yet which is the what I'm going to do first so movie entity now my movie entity is going to look like the same as this one actually it's just the same thing but the entity will be for uh actually what is it will before storing this in uh the database the difference is here first of all we need to make the ID as the primary key so just put a camera here and then annotate this with primary key and then we need to add another thing let me create space which is category because from the API we don't get the category of the movie because we search for like popular movies but when we get them we don't have something here that tells us this is uh the popular movie or an upcoming movie so we need to do that ourselves so just go in a new line and V category which we be assigning by ourselves category that is of type string okay yes this is it now for the movie what is this what I'm doing uh yeah entity because I read da in here and I was like I mean d and I was like what's going on this is entity so this is the movie entity and yes actually for the entity so inside now our Dow we need to make this a list of movie entity so this is now for updating and searching list so or if if you are inserting something that already there then it will be updated if it's not there then it will be inserted that's that's why it's called appert and it works just fine the second thing if for for getting a movie by ID to display it in the detail screen so uh suspend fun get movie by ID that will take an ID of type int and it will return a movie entity we annotate this with query to specify that we want to get the movie that has such an ID let's just create space so how do we now filter this we can say select this is how you can use uh room database and to say from like this this little star is from uh movie entity uh move movie enti where uh ID is equal to ID so what I'm saying here is that from our movie entity uh basically this is the entity we're going to search our database and find uh The Entity that has such an ID which is this ID actually basically this is now the ID and this ID belongs to the movie entity it shows an error here maybe I just need to rebuild and the error will be gone I'm now going to copy this function and paste it to get the movie list by a category so get movie list by category and here we say select from movie entity uh now category uh here as well category and here category is actually a string now oops string like this so what we're saying is that search but will be returning now a list this one a list of movie entities not one movie entity so we'll find all the movie entities that has this category in them so this one the one that will pass basically and then we put that in a list and return that so that's how room database works I explained this in a previous video you can check that now let's actually create our database so our database let's call it Movie Database and that is an abstract class abstract class and we'll annotate this as room database is just a bunch of annotations so it's really simple so we're going to annotate this with database actually and then the entities this the first thing we need entities is going to be our movie entity class like this and then the version so the version of the database in case you've changed something later then this version will be different inside now here uh our abstract class we need to uh first uh extend the room database class and we need Constructor for this and here will we will have one variable which which is for the movie da so abstract V movie da that is of type movie da I guess the error may be gone now or I still need to BU able to make this error gone I thought after writing the database it will be gone but this is now it for our local database now what we need to do is I'm going to create a domain layer in which will have my repository and the domain or the movie domain Bas uh model actually not the domain so here domain we will have inside uh domain actually is INS inside here so This one belongs to this future of the movie list future you could say inside here I will have a package called module I mean modu in which we have all my modeles I don't think this is how we spell that I guess this is how we do it so inside my model I will have one thing which is movie and what movie is is just what we already have here it will look just the same as the entity with one little difference so we'll call it movie oops I don't know what happened I thought I pasted that but it's called movie what's going on here I don't have an idea I want to copy this and paste it here inside modu but it's not pasting I think I will restart my IDE and I'll be back so after restarting the IDE now we just it's spaced I think I don't know but is the arrow going to be gone not yet I still need to build but this is the movie uh model I just need to remove Epi key from here and yes it will just look like the entity but there is one difference actually these are not knowable so I should remove these and I'm just going to paste because there's no point of removing them in front of you so like this and the same actually for the movie entity these can't be null that's why I'm also just going to paste it because there is no point of removing them so this can't be null just I paste that to remove those question marks the only thing that can be null is what we get from the remote because it's possible that something is missing but we don't we shouldn't have anything missing inside our database so that's it for our movie module our module now inside the uh our uh domain we'll have a repository package inside our repository package we're going to create now our movie repository which is going to be an interface uh movie list repository and that will have two functions to get a movie list and to get one movie basically spend fun get movie list and uh this will need some parameters first of all uh the first one is called Force fit from remote and that is a bullan so when we pinate then this needs to be true because by pinate I mean when we scroll down so when we get to the bottom then we need to say this is true to force the remote to give us new movies to display here but when we don't Pion it when we just for example close the app and open it again then we don't need to get movies from the remote we just get them from the database that's why we have this variable here and then the category of the movies that is string and the page that is increasable basically and we'll return a flow that is actually one class that I need to create so first of all um I did not create a video about flows yet but I will so the first thing is actually I need to create a UIL package in which I will have different things I'm actually going to paste them I'm not going to write them but I'm going to paste them and then explain them let me just explain this because I already explained them in previous videos and they just take too much time to write them but I'm going to explain them and I will explain them one by one the first one we need actually inside this flow is the resource I already showed you what this is in a previous video I'm going to fix the package name I guess the resource class is just something we use with flows basically that when we try getting movies the first thing we want is to send that we started loading and then when we get the movies we send the uh movies with this data so this one is of type T so it can be anything can be anything basically in our case it will be a list of movies the data is going to be a list of movies that we say we succeed on getting them and then loading set that to fals after we finish loading that's why we need this resource class in case there is an error so so we start loading an error occurs either there's no answer connection or something's wrong whatever then we send a message with that error that says we couldn't the data or or HTTP error or anything and if we want to have like some default data basically we can still pass that with this one if not we can just leave it no so after that we can then just say now we're no longer loading that's why we need this resource class and what else do we have the screens uh I explained this in the pre not the previous video but in a previous video why we need the SE class to create screens so we have different screens here home popular upcoming detail screens that all inherit from the sealed glass and each one with its route now the second thing is the category we have two categories let me just do this popular and upcoming so I just have them inside an object like this so I can call them whenever I wherever I want in the app then the this one is the average color basically I don't have to explain this because I personally don't know how it works but it helps us get this average color as you can see this image it's fire it's kind of brown and the orange and the average color is this one so we just pass a bit map for this that we can get from our image and then it returns for us a color that is that average color and I'm not going to explain because I don't know how it works this is kind of complex it use some pixels in math and read green blue colors and stuff that I don't know and then last thing is the written bar which is something I also made a video about which is just a re bar composable in which I'm going just leave this as default I want to have five five stars I pass the rating that I get from the movie and then the color will just stay yellow to have now this written bar like this so this is the Stars modifier to get the Stars bigger or smaller and then this is the entire row modifier if I want to surround this with some color or anything or have some background color so yes this is what we will have inside our util package I'm not as I said I'm not going to write them because that's a waste of time so inside here our flow we return our resource that I've created and that is of type movie So eventually I need to add a new one in fact not movie but list of movies basically so that is a mistake this one is resource I was like what is the error this one is resource which is this one and yes we just need to actually import the fine or the right flow which is from cortines this one so we return now our Resource as I said we'll check uh I mean we'll be load in when we succeed we get the list of movies and then we say we're no longer loading and then the second function is going to be I mean suspend fun get movies one movie basically to display that inside our uh details package so that will take an integer and again it will return a flow but in this case it will be a resource of type movies so we only wants one m v so this is now for our repository now we're going to create an implementation for that inside in fact this is it for our entire domain layer or package now inside our data we'll have another package called repository inside this we will have now our implementation so M list repository implementation so this will extend from the movie repository like this and then we need we need to implement some functions the two functions but first of all let's just actually Implement dger Health with this I explained this in the previous video which is about dger health you just go to a new line here so we inject the Constructor or actually I don't don't have a Constructor so inject uh Constructor and uh inside our Constructor we need some things the first thing we need is the movie API so private VAR movie API this one and the second thing is the database so private for Movie Database this one so if you don't know what inject Constructor is just watch the previous video then you will understand what this is this is from dils for dependency injection now our first function how do we get the list of movies just to be clear this is actually almost the most complex class in the app the implementation of the repositor I don't know if it's the most complex one but it's such a challenging one uh for those who actually didn't do this before but first of all a flow with flow we can reach a flow or a sequence of actions that's why we use flow the first action is so we say a met uh first of all return flow I forgot to do that so return flow that's what we need to return and then the first action is Emit and then as I said re loading so resource dot loading and set that to true now we are loading so we're trying to get the movies from either the database or the API so the second thing is that we first want I mean the first thing is that the app is a first offline app so we first try getting the movies from the room database if there is nothing from there then we can get them from the API but how do we get them just say V uh let say local movie list and that is equal to the what to the database now so movie database. da data access object to access the stuff in our database dog movie list by category and I think unless I'm wrong I did or I already pass category here I thought I was searching for category but yes just pass category so now we'll get a list of movies based on the category that I paste it can be either upcoming movies or uh popular movies now we check if we should get the movies from the local database in case something is wrong then we'll go to get them from the API so should uh load uh should load local that's what I'm local movies basically that is is that is equal to now our local movie list dot is empty in case that is empty then we have no movies so we're going to get that from the API and not only that and and uh what is that so and not force fit from remote so what this variable does is that we'll check if we if this list is empty and we are not forcing to force I mean we're not forcing to Fitch from remote because even if this one is not empty if we have movies already in the database but we are forcing it so this one is true to get them from the API then we'll ignore this and then directly go go to get the new movies from the API basically for Pion to like because we increased the p in page and now we want new movies so if should load local movies why did I actually put this inside the varable we can just copy this and put it inside here but for more readability this is a better approach now this will admit so another action that we want as I said now a success action so resource do success with that success thing we'll pass data that is our local movie list but there is one thing what we want is a movie and what we have is a movie entity so if we check this this is a list of mov movie entities but this one returns a list of movie we need to create mappers for this what mappers is is just to map an object to another especially in our case a movie entity is the same as a movie so they have the same data but the they're used for different purposes that's why they are the same so we need to create uh in fact a first different package called mappers in which we have different mappers if we have them inside here we'll have our first map I mean one mapper basically not many so movie mapper we have one mapper that is a class uh not a class just a file and the mapper is just a function at the end so movie entity which is in fact an extension function movie entity dot to movie so we'll map this movie entity to movie and inside our movie entity we have a atory but in movie we don't pass the category just like that but we need to actually pass it manually so category this is of type string and that will return for me a movie so like this and return movie now all the different types we need inside our map so for example back something thing is back something backdrop path so what this means this backrop path is from our movie and this one is from our movie entity so we're mapping what we have in our movie entity to what we have in our movie and I'm not going to write them because that's a waste of time I'm just going to copy them and paste them so all of them including the category the last one is the genery ID so genery IDs that is a list and technically we can't store a list inside an we can but in we need a work around for that inside a database or an entity what we need for this uh movie has that as what is it what is it as a list of integers but entity in fact that's something I didn't explain but in entity what is it it's called generes it's a string even though what we are getting from our dto is a list uh because it's not really easy to store a list of integers inside uh a database that's why I convert them to string so now they are already a string now but I will explain how to convert them but they are string now so how do I convert them to a list of integers back so how do I convert them back by saying now gener ID is that we get from our movie entity do split so that's a string and then we split that string with commas so why in fact I think I first need to create this second mapper actually not this I leave this one to the end so I could explain to you what's really going on here with this mapper the second uh the second mapper or basically actually normally the first mapper this is the first mappers fun movie uh dto do to uh to movie entity that will take again category of type string and it will will return a movie entity and uh open the brackets like this and then we'll return a movie entity so right here I'm going now to paste the first ones but not the last one so I would explain what that does so these are the first ones basically this adult is inside movie entity and this one is what we got what we get from the movie data data and since that's nullable so that can be null uh we use this to tell if it's null then assign fals if this one null assign an input string and uh some default values when that is null but for the you can hear birds like us we have Birds inside the house so in the movie generary ID uh in the JY IDs that is going to equal to try gener IDs and it's notable that's because this is what we get from our mov d o uh dot now join to string so what this means is that we have a list of integers and then we're going to join join them in one string so that's literally what I'm doing here because it's easier to store a string inside a database and that's going to be enjoyed uh or the separator is going to be a comma so all of them will be inside the string all of these integers we separate them with a comma and in case that is null so if this thing is null we could say this Str is then the default Val value is just going to be minus1 and comma min-2 so if we don't have any integers anyway then this is going to be the default value and in case this crashes for any reason then we'll catch that and that will be an exception like this and the default value when that crashes is going to be the same like this so I'm converting a list of integers into a string and I join them with a comma Now I want to convert back that string into a list L of integers so I get now the list uh the string and I split those strings and I split those integers inside that string with those commas basically and then I map that so I get a bunch of integers now after removing the commas uh I get a bunch of integers and I set it to int oops to int because they are strings but now I convert them to integers so what I do here is that a lot of integers that is are inside this string I convert them to integers of a list of integers I know this is complex but it makes sense once you understand it hopefully if you understand it and then in case an exception happens then the default value will be a list of default integers like minus one minus two so this is it for the mappers hopefully you understand them I don't know if I explained them well but yes that's what they are you can rewatch this section if you don't understand them now inside my implementation of the repository uh we have now a list of movie entities but the required is the a list of movie so we say map and uh now we get just movie entity and inside here what we are going to say is movie entity do to movie the map we've created we've created and then pass the category now we are mapping the movie entities to movie to movies basically and uh that's it we emit our resource and then we tell it we no longer load so by just copying this and P in it after this one we don't load anymore so set that to Falls and return the flow so this is it when we get the movies from the database now how if you want to get them from the API so this is now a different things so if in case we forc to load from remote or this one is empty we want to get them from the API basically the first time we launch the app then the that's empty so we load them from the API that is going to be a VA movie list from API you could say from remote whatever you want to call it try in case an exception happens so we'll try doing this movie api. get movie list pass in the category pass in the page and that's it we can get the movies like this from the API but we can get accept itions basically so catch and actually different types of exceptions so the first one is an IO exception and we'll catch that and just first of all let's print the print the stack Trace to know what's going on and then we'll Emmit a failure here so resource do re uh error and then the message so message is going to be I don't know error you can have the better error handling or exception handling but for the Simplicity error loading movies that's what I'm going to say we can have an IO exception and uh now the other errors we can have or exceptions we can have is a an HTTP exception and a general exception like this these are the type of exceptions we can have now after getting our movie list we want now to map that into a movie entity a list of movie entities to store it inside the database because they said this is the first offline app and if anything we display in the screen or in the app is what we get from the database not from the AP so even if we get these from the API we first store them in the room database and then get them from the database because this is a first offline app it works in offline mode so V movie entities that is equal to movie uh list for from API do results I don't know is it this one uh just let me just see what's going on here it says unit first of all need to return the flow here that's why low but right here I need to return a list that's the mistake so a list or not a list but a movie uh list dto so movie list dto which is the one that we' created with the plugin that's the mistake I made here I forgot to return something here but in fact I needed to return that list to result now we have the results do lit to make sure that this thing is not null it do map so now we'll map the movie dto we already created the mapper so map it so we'll have in here we get a movie dto so we'll map this so in a new line movie dto dot to movie entity pass in the category and actually uh we created an entities uh that we get from uh the API and then Movie Database to store that inside the database do uh movie dow. upsert movie list and that is going to be movie entity and we uh Amit a success basically so emit uh resource. success because we succeeded on getting the movies from the API and then storing them inside the database movie entities. map but now we need to return Again movies not in map P to movie category and then Del it that we no longer load going back here this is it just copy that and paste it right after that and I think actually this is it for this one that get in the list of movies the last one is going to be get in one movie so just a recap what is going on here we return a flow which is a sequence of actions the first action we tell it that we start loading the second thing this is an offline app we get the movies from the database in case that is empty and in case we force uh loading from the remote then I mean in case yes in case we force loading from the remote then we'll ignore this if that's true so that is not that is not empty in fact this one is not I made a mistake so in case that is not empty in in case we don't force loading from the remote then this will be true we'll emit a second action as I said a sequence of actions a second action that is a the success and then we return a movie a list of movies basically that we uh map from that we mapped from this uh local list and then we uh third action and The Last Action is that we no longer load and return the flow if this is false we want to load from the remote create a variable that get those movies from the remote and we get a movie list D in case ex exceptions happen then we catch them IO exception HTTP exception and general exception and then we map this list of movies that we get from this result that we have inside the dto in case it's not null basically that's we have this lit block map that to mov The Entity store that inside the database the action here which is technically the second action because these won't execute if that is false the second action get the list of movies The Last Action we no longer load and we're good to go now when we want to get one movie by ID then we want to have the same thing basically so return a flow and uh I think I need to have an extra bracket like this so return a flow that's it we say now we're loading through and then Va movie entity because we have one entity that is movie database. dow. get movie by ID and passing the ID and uh if movie entity do I mean is not null so just make sure that that is n even though it shows this but I don't know for safety if that's not null it can't be null technically because it's not nullable but still just check that we want to emit now the second action which is resource. success and uh we'll pass our movie entity. to movie uh and then the category which is movie entity. category because we already stored this in the database so we now already have the category and uh The Last Action is we no longer load so oops right here set that to false in case we don't already have this movie Inside the database or that is null uh but return the flow if that is null met uh resource do error and then we say error no such item or anything no such movie for example and then the last thing is that we want to tell it that we no longer load this is it for the gate movie item once you understand this basically this is how you can get things from the database in case they don't not they're not there get them from the API and then store them from the in the database this is it for the implementation I don't know if this is the complex one but this is it now for this video the first part of this video is creating the data light of this app I don't think there is anything missing yes I guess this is it now we created the data layer for our app and uh in the second part of this playlist we'll start now creating the presentation or the UI for the app so see you in the second part don't forget to follow me on Instagram and uh subscribe to my YouTube channel to get uh new updates in Android development so see you in the next video and bye
Info
Channel: Ahmed Guedmioui
Views: 10,344
Rating: undefined out of 5
Keywords: android studio tutorial for beginners, android studio project, android studio app development, android studio app, android studio app project, kotlin android tutorial, kotlin tutorial, kotlin multiplatform, kotlin full course, jetpack compose tutorial, jetpack compose android, jetpack compose mvvm, jetpack compose state, jetpack compose viewmodel, jetpack compose vs xml, jetpack compose app, api key, jetpack compose animation
Id: z3upO8AFLO4
Channel Id: undefined
Length: 53min 25sec (3205 seconds)
Published: Sun Dec 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.