Build a Local-First Finance app with Expo & WatermelonDB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up NJ developers welcome back to a new live stream and today we're going to build a local first finance application using R native Expo and watermelon DB so for the text tack on the front end for the mobile applications we're going to use re native with Expo so we're going to build an application for both Android and iOS and maybe we're going to test it on web as well and for the routing for the navigation we're going to use Expo router but actually the focus of today's video is going to be more around how to use watermelon DB to build a local first application previous week we tested realm as a local first solution and a lot of you were interested in seeing how watermelon DB would work in this situation watermelon we are going to talk more about that but uh it's a local database built on top of SQL light and it's really powerful and uh with it you can build like really performant local first applications so what you will learn in this tutorial we're going to start by setting up a new Expo project we're going to build and style the UI of our application it's going to be a unique application I'm going to talk about that later we're going to configure watermelon DB in an expo project and this is going to be very beneficial because in V documentation we don't talk a lot about how to do it in Expo only Rec native CLI but it's possible to do with Expo and whenever we can uh we should try to to use Expo because it's going to be much easier in the future to maintain and upgrade your project we're going to also learn how to create an expo development build because we're going to use some native code and we're going to learn more about how to work with watermelon DB to build our local first application how to set up our database our schema how to read it how to observe changes and update automatically our UI but question is what exactly we will build in this application uh this tutorial is a bit different than our usual let's clone X application because in this tutorial we're going to build a quite a unique application that I at least I didn't see out there and this is going to be an actual application that I personally need and most probably I'm going to launch it on the market but we'll see we'll see how it turns out so the application is going to um let's I I need to give a little background about the whole concept that we're going to try to cover and why this application is needed so this idea came to me uh after reading the book profit first which is a great book um and after reading it I applied all the learnings in running my personal business so um that's that's how we got to this tutorial so in this book uh I'm going to try to very to simplify ID and to Focus only on the core of the concept um the idea is that if in your business you have all the money in one account it's going to be very easy to spend all of this money and then you end up with no profit uh what Mike the offer is uh suggesting is creating separate accounts separate bank accounts for different purposes and one income account and then every month you go ahead and distribute this uh money uh among different accounts that you have set up so that for expenses you have a dedicated amount and you never go uh and reach to to the other accounts and other account can be for taxes so here is a bit of representation of how it works we have one common account at the top the revenue that will uh pour the money into the different accounts for different purposes so the first step is you create like separate bank accounts and then twice a month you have to go ahead check your revenue account see how much you've got and then based on a predef percentage that you have set up for yourself you're going to distribute this amount through different uh smaller plate account so that's that's the idea like instead of having one big plate that is easy to spend everything you instead have more multiple smaller plates dedicated for a specific need and based on the book like this should actually be like separate bank accounts you cannot do this in a spreadsheet but the problem that I encounter is that U still like once or TW twice a month like I'm going to have to go and calculate all of these based on percentages and Van uh for that I created a spreadsheet so all of this is happening like in a spreadsheet um and that's where I was thinking like maybe I can do this calculation and distribution much easier using a simple mobile application and that's exactly what the application is going to do it's going to help you keep track of all your accounts and the allocation percentages because these percentages are changing throughout the time uh it will simplify the allocation process by automatically calculating the allocation amount for every account when you're doing this twice a month and it will keep track of past allocation so you can have a nice insight and see how your business is doing uh maybe we can integrate even some graphs to show how everything is changing over time uh and in future it can also send reminders push notifications to remind you to do uh the allocations from the UI perspective uh here are some simple mocks that I created uh we're going to have the first page is going to be the accounts where you're going to set all your accounts then you're going to be able to add an allocation and here you're only going to have to input the income and then based on the percentages that you have for all accounts is going to automatically display you how much you have to send to those accounts and then it's going to provide a history to see like different allocations in the past maybe some graphs here in the future uh to to improve it so that's the plan that's a nice application I think it's going to be very good for learning about watermelon DB by building this application because there are some nice relationship between all of these small models it's simple yet it we are going to manage to cover all the topics about uh watermelon and build this application so if you're ready let's roll the intro and let's get [Applause] [Music] started all right hello everyone who is joining us live how are you doing guys so um let's go ahead and right away open a terminal and let's initialize a new Expo project navigate to where you keep your projects in my case it's here and let's initialize the Expo project by running npx create Expo up then I like to add at latest to make sure that I'm using the latest version and not uh something that I already have uh and let's give it a name let's do profit first let's press enter we're going to initialize a blank application and then we're going to go through all of the configuration set up we're going to install and configure export router together and if you're new here hello my name is Vadim H welcome to to this channel here and not just da my mission is to help you build uh impactful mobile applications um so if you're on your journey to learn more about reck native to build uh mobile applications make sure to subscribe to the channel we have a lot of Project based tutorials here and we're having a lot of fun building them so subscribing I would appreciate that a lot anyway Let's uh see the live chat where is it while our Expo project is uh initializing hello elos Sergio Ivan J student reelio so many people live how are you doing guys thank you can you host your Expo application on web to see how to do it please um maybe we're going to try to do this for this application but I cannot promise because uh specifically like waterml andb like we have to use a little bit a different driver but we're going to try let's see how we manage to do everything by the end because we also have to cover the UI to cover the the watermelon stuff so can we do full stack in react native yes and a lot of our tutorials on this channel are full stack in fact this is one of the only tutorials that are that doesn't have a backend however uh similar to how we saw in the previous tutorial of the possibility of synchronizing your local database with a remote database you can do the same with watermelon DB I'm not sure if I'm going to have time to show you the synchronization to today I'm going to focus on actually local first or let's say local only at this moment but I'm going to show you a good article uh that will help you do the synchronization so pre pre pre prev all right so let's go ahead uh here we have our project ready so let's open it up in Visual Studio code by writing code and then profit first the name of our application and we should uh open it in Visual Studio code we no longer need the terminal so I can close it here and let's see what do we have at the moment come on okay going to make sure you can see everything so before I jump into the um no actually the first step I like to to do here is moving from JavaScript to typescript even though we might not use uh all the typescript features where we might not uh have a time to type every single thing having typescript is going to help us keep everything um typed and uh to do that simply rename the app.js file to up. TSX and after that let's open the terminal you can do that from the top new terminal and let's run with server using npm start now when doing npm start Expo will see that we have added some typescript files and will ask us if we want to install and configure typescript let's press yes and Expo will install and configure typescript for us we create the TS config for us and our up. TSX should not should look good without any errors and later in the same terminal we should see the our development server running if you're new to Expo the easiest way to run this application from this point is going to be to download the expoo application on Android or iOS and then scan this QR code in that case you don't need any uh extra environment setup but if you want to run it on Android or iOS simulator you would have to configure uh Android Studio with Java ZK and for iOS You' need X code uh to to run it so yeah easiest way go with Expo go if you have already Android studio and simulator let's just press I to run into an iOS simulator or in your case a if you're working on a Windows or a Linux machine to open it on Android after a couple of seconds we should see our application running and we see open up abdj to start working on your application so here is already our ABD TSX and we see a text um element here and we can try to change it to hello world save and it will automatically refresh and display on our uh device maybe I can make it the device a little bit bigger so you can see it better and with that come on where is it oh here it is cannot make it smaller I'm going to do it like this probably uh it's still visible so let me go ahead I will try to keep track of all the changes that we're doing and later you're going to have access to the repository so let's do a git add git commit minus m in it Expo project perfect okay so what's going to be our first steps first steps is going to be setting up Expo router because we're going to have our application is going to have a couple of screens so yeah let's go ahead set up Expo router and set up a couple of screens that we will need uh the screens that we will need as you can see here are the accounts allocations add allocation so yeah for that we're going to use Expo router let's open the documentation of Expo router from Expo documentation and if you're new to Expo router this is a file-based navigation system developed by Expo uh which is built on top of rack navigation most probably you heard about rack navigation where you have worked with rack navigation so everything that you know and that you can do in rack navigation you can do in export router as well the only difference is with export router it helps us automatically configure and create these routes by simply creating files and folders so instead of manually doing the configuration through uh through scripts through files uh through script yeah um we are simply creating a component a file and then export router is going to set up the route for us so let's see how to configure it in our project uh here it is uh go ahead if you you are interested check more information here we also have a bunch of tutorials on exper out on our Channel but I'm going to go to the installation guide and instead of a quick start that shows how to start with a template I'll go ahead to the manual installation to show you how you can install it manually in any project so after creating the XO project we need to install the dependencies let's go ahead and copy this command from here let's open back with terminal let's clear and let's paste the installation command to install export router save era context native screens constants status bar and so on I see that my camera is not very well displayed there but what can we do I had some issues previous stream with a camera so after that is done let's go back to the documentation we need to change entry point uh basically the first file that is being rendered by R native when when opening the application uh we're going to copy this entry point and we're going to paste it in package.json under the main field so instead of up entry it's going to be export router entry now going back we need to add the scheme which is going to be used for deep linking which exper outter automatically manages for us so for that open up ABD J ABD Json in here somewhere for example under the slug add the scheme which can be profit uh profit first now if you're developing for web we can also install these dependencies uh so let's actually install them because it doesn't take too much time and if we decide that we are going to have time for web as well we're going to do it so go ahead and install R native web and R Dom and what you have to do is to change the in up. Json for web change the bundler to Metro but I believe that this is the default anyway you can go to up. Json web and here under the fa icon let's do bundler and set the Metro which probably should be the default default Falls to webpack only if webpack is installed if not defaults to Metro so yeah I believe you we no longer have to manually specify it but anyway so the fifth step is to uh to add this B preset Expo in B.C config but if we check it it's already here so nothing to do here and lastly we have to restart our server by by clearing the cache so let's go ahead let's check the terminal where our server is running let's stop it by pressing contrl C or alt see on Windows I don't remember and now we're going to run npm start but this time with Das Dash space-- clear which this will clear the Metro bundler so that everything is fresh and now we can even close everything come on and run it again come on uh where is it let's press again I to open on iOS here it goes and we should be welcomed with this uh default welcome to XO screen we see this because we don't yet have the app directory for Expo this is important the up directory is where Expo is looking for your screens we can press on this button but I recommend not to do that because uh I'd like to create the app directory inside a folder called Source SRC then inside source let's do up directory and in up directory we can have the index. TSX and this index. TSX will become our home screen so what we can do is probably copy everything from up. TSX let's copy it from here bring it to index. TSX let's rename it like it doesn't matter but um just not to confuse ourself rest name for up to home screen because this is only the home screen and then let's save and reload the application I hope that Expo will take the new up directory that we added automatically if not we can uh restart it with clear cache but we see the hello world or let's say here home screen like this so this is our home screen so lastly we no longer need the up. TSX file because this was the old entry point of our application now our application is inside this up directory I'm going to also create a new folder here under the source called components because we code um displace it displace it weirdly if it has only one child so for you not to be confused not to be confusing so we have source and then we have application and here is where all our screens are going to be located for example the index is going to be our home screen or the home screen if we look at our yeah let me actually go ahead and Comm commit G status get add get commit setup Expo router and now let's go ahead and create a couple of screens so uh what do we have here we have we have which is going to be our home screen I think that allocation like when you open the application you want to see like previous allocation and maybe a button to go ahead and create a new one so the index will say something like allocation and as you can see from here we're also going to need another screen the first one called accounts to create a new screen in Expo router all you have to do is create a new file under the upd directory let's give it a name uh account. TSX and from this file we simply need to export a component a screen so let's go ahead and Export default function account screen and a r native component it's something that renders something so let's maybe open uh import here A View maybe a text from react native react native and render here A View which is a container and inside it a text saying accounts okay at this moment we do not see it but what actually we can yeah at this moment we do not see this accounts page because we are actually on the index page on the mobile it's a bit different like to uh to to do the navigation but on the web if we go ahead in our terminal and press W to open it on web our application is already running on the web let's wait for it to load here we see like if I'm going to zoom in allocations because this is the home screen but if we navigate to slash accounts we're going to see here at the top accounts and the SL account is coming directly from the name of our file so what happened here is we simply created a file exported a component and exper router set up the route for ourself so we can navigate there on web that's easy to do through the navigation bar on mobile the navigation will happen uh will happen through a component called link or there are other method as well like using the router but the easiest way is using the link and I'm going to import the link on the home screen in the index link from exper router and let's go ahead and Below allocation let's display a link that will say uh go to account and the link needs an HRA property basically similar to how an a Link Works in HTML we need to provide the puff to the to the screen that we want to navigate to so that's going to be slash and then the name of our file accounts so slash accounts now if we simply press on this go to accounts we see that we are redirected to the accounts page we cannot go back at the moment we're going to cover that in a second but anyway we have this uh two screens and a way to navigate from one to another you can press Double R to reload the application and go back to the home screen okay so these are the two screens the home screen with allocations and the account screen that we're going to have later what I want to do now is I want them to be in a bottom tab Navigator so a bottom top Navigator it's super simple to set up with export router the only thing the only thing that if you're new to exp router that might be a bit confusing is the layout file so the files that we have in our app folder they are our screens they have a URL a puff and we navigate to them but we can also Define a special file called layout. TSX and if we also export a component from here export default function root layout the name doesn't really matter but because we are this is the first layout in our application we're going to call it root lay out so now if I don't return anything like if I return all we see that we don't see anything on the screen that's because layout is the file that wraps around all the screens in our folder so both accounts is going to be inside the layout and the index is going to be inside the layout and by returning null we are basically overriding it to get back the functionalities that we had before when we didn't have a layout or what was happening automatically like by default is going to be simply random in a slot here so the slot what the slot is doing imported from export router is basically saying simply render the child component the slot becomes the child component like the screen so now everything is back to how it was working before from here instead of rendering instead of rendering the slot we can render different types of Navigators for example we can render a stack we can render tubs and so on so if I change from stack to from slot to stack we are going to see the header at the Top If I go to the different account we see a stack Navigator with back button and so on so that's how easy it was to move from a from no Navigator where a very basic navigator to a stack Navigator and behind the scenes this is using the stack navigator from react navigation now if I will change this to tabs we're going to see tabs at the bottom index and accounts index and accounts so that's exactly what we needed to Simply render the tubs but now explaining the layout I hope it makes a bit more sense like how it works so the layout in simple words is the component that needs to be shared between different screens in the same folder so so the logic about the tubs like what we see at the bottom is the component that is shared between both index and accounts it doesn't change it's the same perfect to change the um to change the names here from index and account what we can do uh because at the moment it's simply taking them names of the files but if we want to adjust them I'm going to go ahead and expand this tabs component from a self closing tag to a tag that opens and then closes and inside these tabs come on inside these tabs I can do tabs do screen and then closing tag and with tabs do screen we first have to Target the screen that we want to adjust using the name so the name is the same is the name of a file index for example then using options we can adjust anything that we could do in react navigation so for example we can change the title to accounts if I do that now at the bottom we see accounts at the top we see accounts we can do the same for the second screen called well well the index is actually not account but allocations and then account is going to be accounts with capital A so allocations and accounts perfect we can also adjust the um how's it called the icon tab bar icon which is probably going to be a component that can also give us the color how is it called focused color and size so size and color and then we can render um an icon using Expo Vector icons so let's go ahead and find some icons from Expo Vector icons so we need for account I don't know yeah probably this is going to be good so let's go with uh material icons let's import it at the top of our file and then render these material icons for the toab bar icon but instead of hard coding the size let's use the size that we receive here so it's going to be more Dynamic and for the color as well like this so actually this was meant for for our accounts here and then allocations probably should I do this one allocations will it look good let's see how how is the name I think it's also material icons account slash3 so this is our allocations and these are accounts okay so perfect we have two tab bars we we icons everything looking good so far let's go ahead and do G add git commit minus M and this is going to be our bottom tab Navigator let's see uh if you have any questions so far oh question is watermelon uh better than super base they are very different so uh watermelon DB is a local database that lives on your device it's an based on SQL light so that means that it will be stored on the device that the application is running and it's good for a lot of use cases but whenever you delete the application you're going to lose the data in that database as well super base on the other hand is uh helps you create like a cloud database based on postgress SQL so in case of a super base you have an actual back and you have a data stored in the cloud the cool thing is that you can put them two together you can have watermelon DB locally so your application writes and reads instantly and then you can have watermelon DB synchronized with super base so that you have the benefit of Both Worlds local database for performance for being very Snappy and fast and also allowing users to use the application even if they don't have uh internet connectivity and then synchronizing with super base allows users to save their data in the cloud maybe also um um collaborating on the same data from different devices for example if I want to use this application on my phone and on my tablet and on my computer without super base I'm not going to be able to do that because all the water Mel theb is going to store the data locally so it's going to be separate from all the accounts now if I connect everything with super base I'll be able to access the same data across different devices uh so later I'm going to show you the uh a to um tutorial how you can synchronize watermelon DB with super base from Benedict uh so yeah it's with a couple of scripts you can synchronize that and have everything working both local first but also synchronized with a cloud thank you so much for using watermelon yes excited about that I actually used it in the demember but I had some issues so it was uh giving me some headaches on configuring and installing so let's hope that today is going to go smooth watching from Ethiopia hello love your videos thank you very much whatever in your city right now for me like it's always summer or late spring so it's quite um hot outside my camera is hiding the TBS okay so sorry but now it should look better so here are the locations and accounts let's see what our comments please show us how to make the synchronization okay we're going to have then to uh to hurry if we want to manage or I think yeah I think that's an important topic to show the synchronization so even if we don't manage I'm going to see maybe we we will do the part two but yeah let's let's try to do it today I yeah uh can you show us how to run Android and iOS application using XO build without expoo yes we're going to do that today because installing watermelon DB we need some native code and in that situation we need to use XO pre-build so we're going to show you how to do that easily just react I'm working on watermelon DB only let's see if anything helps uh are you using watermelon DB or you are working on the watermelon DB if you are experienced uh please stay here I might need some help but it's going to be fun hola Venezuela hello [Music] hola I love way you teach thank you very much Expo go or react native CLI which is best for big projects uh for any project size Expo is the my recommendation because it's going to allow you to upgrade much easier it's going to allow you to use the whole ecosystem way better and uh to get started you're going to use expoo but at the moment where you're going to need some native code you're going to use a custom development build which is in a in simple terms your own version of Expo go so there is no reason not to use Expo and even with a custom development build Expo is going to manage your project so I'm going to show you that in a second when we get to the when we get to it yes using npx exp for run iOS you can create a development build m i late nope we are just setting up our screens so let's continue because I see that you guys are very interested in seeing a lot of features today so let's go ahead and um continue uh what there is another thing that I want to cover from the perspective of Expo router and I think it's going to be better to do it now so that later we can focus only on the UI and have like the exper router set up ready and here I'm talking about the the third screen which is called ad allocation let's go ahead and start step by step uh thinking that okay other location it's another screen similar to accounts let's go ahead and wait yeah it's a similar way as the similar screen as the other screens that we have so for that we need a new file and I'm going to be lazy and simply copy paste the account and rename it to uh maybe not other location but new allocation or create allocation or or yeah new allocation is good and let's render here do change the name of file even if even why it's not needed um because we're not manually importing it anywhere expor aor is handling that like it's better to have them perfectly not to confuse ourself new allocation screen and here let's do new alloc allocation if I do that what's happening is a new tab is being added to my bottom tab Navigator new allocation the problem is that I don't really want the add allocation to be a new separate tub I want the new allocation to be also part of the allocation stab so we have a locations where we can see a list and the new screen and the accounts there the only tabs that I want for now so in this situation what we actually want to do is we want to Nest a different Navigator inside this tab so that means that the tab that we have here a location we don't want it to uh display only one single screen we want this tab to be able to display multiple screens inside for that we simply will replace this screen with another folder this way we are nesting a navigator inside in our Navigator so let's see how to do that first let's create this new folder and we're going to call itations allocations now let's move obviously the new allocations we're going to move it here move um and probably the index as well because the index is our allocations right right probably going to give us a bit of headache but we're going to see now uh nothing has changed because we still have fre tabs because by simply creating a folder ER it will only change the puth to that screen so now if we look at the web version it's going to be simpler to go to these allocations we are actually going to slash allocations slash new allocation and here to Simply SL allocations so the folder simply changed the puff the location of our screen and how we navigate there but to create a nested Navigator we will have to define the layout file of this folder this is going to be export default allocations layout I forgot to export default function and here we will return another type of navigator for example we can return this as a stack navigator meaning that the the screens inside this allocations folder the index and new allocation should be rendered as a stack Navigator now if we look at the bottom tabs we should see only two tabs now and that's actually what's happening because in the root Navigator in our application we have account and the folder allocation but it's still two things two tabs so we can go from allocations to this one and the allocation itself if I go to allocations here let's go to the index and instead of go to accounts let's write new allocation and let's navigate to slash the name of the folder allocations Slash new and maybe we don't even need the word allocation because it's going to be duplicated we already have the word allocation on the folder so the file new is obviously that it's a new allocation so in the index it's going the the URL to that file is much better allocations Slash new now if I'm going to reload we will see that we do not have any index file and that's because uh we do not have a index file inside our application we moved it to the allocations here that's a bit tricky I can add it as where in the application let's add it as index. TSX and this is going to be a simple component that will be the home screen let's say here home screen we're going to see how to better do it but just to make sure that it works so this is the home screen a bit we're going to fix a bit the the titles in a moment but let's go to the last folder allocations and here where is this text called new allocation if I click on it we see that we are still inside this bottom tab Navigator but we have also on the top a new um stack navigator from which we can go back and at the same time we can navigate through the other tabs and go back and we're going to still be here for the on the new one so this is how we can Nest a stack Navigator as part of one tuab screen let's go ahead and fix some of the stuff in the root layout we have the allocation title it's not intended for the index it's intended for allocations directory so allocations if I save this and do reload we see it here as the first allocations allocations and for allocations while we're still here index new index new we have two a set of two headers one of them is coming from the tumbar another one is coming from the stack Navigator I'll go ahead and actually instead of changing the ti in I'll go ahead and I'll hide one of them and I'll specifically hide the one from the top bar because I will need the one from the stack for the back button so on the tabs for the allocations let's do header shown false and this will simply hide the header now we don't have a header from the TBS we only have a index here if I go to new allocations we see new here and I can go back perfect and we can do the same adjustments uh for the title but already on the stack Navigator here so uh previously we saw how we can do the options through the layout file but that's not the only way you can actually adjust the options of one screen for example here on the index through the screen Itself by simply importing the stack and rendering the stack dot screen and then sending options in this case we don't even need to send the name because we are inside the screen so stack. screen we know that we want to adjust the title for this screen so the title is going to be um allocations so instead of index now we should see allocations no why options uh because I I I'm somewhere different because yeah I'm on the home screen I need to go on the allocations yeah now the title is allocations and I will do the same for the new so on the new I'm going to render the St and I will title it new allocation so if I go to new allocation I see it this and the back button is even better so everything now works perfectly uh now the question is what do we do with this index screen because we don't really need anything we want probably we want to make our allocations the home screen so what we can do is if I reload this is going to be the the screen that I see by default but if I simply return here instead of rendering something if I return a redirect from exper router and using an HRA uh allocations actually SL allocations that means that every time I'm going to try to go on the home screen on the slash is going to automatically redirect me to allocations so now if I'm going to reload we should see that we are automatically on the allocations page if I'm going to try to go to index I cannot go because I redirected back so now I can go through all only these two and to make sure that we hide it from the tab Navigator actually I don't remember how but I think is going to be this way I'm going to go into the tabs do screen I'm going to Target with a name the index file and I think um let's see export router export router hide tub there was think that href n or something like that hiding a tub hre n but on which name oh on the options okay I was trying to do it there so let's go with options and just say HRA null and now it's not going to be visible in the tab bar if I reload we are on the allocations I can go to new allocations from here I can go to the account phones so now the screens are exactly as we needed for for now and on the web that means that if we're going to try to go to the home screen basically to the slash we're going to automatically be redirected to slash allocations so here is this one here is allocation I can go here I can go back so it works both on web and mobile oh perfect so I think with this we have our exper outter set up ready and let's go ahead and do get add get commit minus [Music] M nested stack inside tuab yeah I think that's a good message all right so exper router setup is done if you have any questions let me know if not we're going to move on to build some very basic UI that is going to help us move to the watermelon DB oh just re uh saying is using watermelon DB in re native CLI perfect stay here maybe if you're going to if I'm going to need help I I'll ask why not start with Ignite boiler plate I uh yeah ignite is a powerful boiler plate but I'm always trying to use only the default stuff so that everyone can follow along um easier okay so a lot of people are tuning in today uh the plan for today is going to be to build a finance application a local first finance application using watermelon DB inside Expo so far we have set up the project structure we install and set up Expo router with different screens that we have created now we're going to cover some basic UI and then we're going to get into the watermelon DB setup uh deot thank you very much the Manuel is asking you to hit the like button thank you very much appreciate it okay so let's go ahead and let's go ahead and cover a little bit of the UI uh based on these uh mocks that I have created so I'm going to start with probably the accounts uh on the accounts page here we're going to go ahead and render a list of accounts so let's open the app accounts page and and we are going to render these accounts well first of all every single account is going to be a custom component uh and I'm going to start from that um instead of writing it here and then extracting it I'm going to start by defining one component that will represent where is it that will represent one of these boxes so the Box will have a count name the cap and tap which I'm going to explain in a moment what that means so for that inside the components folder let's create a new component called account list item. TSX now let's export default function account list item and let's return something on the screen screen for example a view with a text inside the text is going to be the name of account for example profit let's make sure to import View and text from RE native and now let's go ahead and render this component account list item inside our application account here under accounts so first of all I'm going to import account list item and I'm going to render it like this maybe I'm going to even render it a couple of times just to be able to see uh how it Stacks together I'm not going to need anything on the top here so let's remove it and now let's go ahead in the account list item and here work a bit with this screen so we have the name of account profits then we have two percentages cup and top uh and to explain what we mean I'm going to show you some definitions here so from the book uh profit first first of all an allocation is the process of sending money from the income account or also called the big plate to all the small plates so this is usually done twice a month um on 10th and 24th you check the income account and then you distribute it to all your other accounts the way you're going to distribute it is going to be based on a percentage that you assign to every single account and there are this top and cup the top is the target allocation percentage this is the goal basically where you're striving towards like for example you want your company to have 20% profit but at this moment you cannot afford that so you're going to work towards that for that you set a goal and then you have the cup which is current allocation percentage maybe 5% so now it's 5% but you want to move towards 20% so I'm going to use this TP and cup uh terms a lot today instead of saying Target location percentage so that's where they're coming here from every account will have a cup the current allocation percentage and the target allocation percentage let's go ahead and render them also inside some text for example 10% and then another text um I know 20% % now let's go ahead and import the stylesheet and start working a bit on the Styles so I'm going to define the Styles here sorry uh now it should be better style shit. create and we're going to have the container of our account we probably will have the name and I don't know percentage maybe so let's go ahead and give that first view the Styles dot container this one is going to be our name so let's give styles. name this is going to be the percentage so styles do percentage and the same for the second one okay for the container let's go ahead head and do I don't know I'm going to start with a background color white okay uh I'm going to give it some ping like 10 to make it better to to to be visible and the amount of space between this account list items I'm not going to manage here I'm rather going to manage it through the through this component by giving Here style and by giving a gap five this will add five pixels between every item that we render and maybe even a padding five to have some spacing around the screen nice okay now we based on our mock we want to display them kind of in a row so let's on the container itself let's do Flex Direction row and then let's do let's spread them apart by using Flex or Justify content space between like this okay I think so far so good maybe we can do border radius five to make the round corners there not very visible but later if we're going to change the colors it's going to be more visible for the name let's do it I don't know uh font weight bold font size 16 increase a bit the font size okay and probably I'm going to leave them like this account account and instead of rendering cup and to always I'm going to render them at the top above the columns here so I'm going to have inside our accounts file I'm going to have a view that will render free text name this is going to be the header of our list then I'm going to have cup and then I'm going to have Target allocation percentage now we should have very similar Style to to our previous let's actually go with a Styles as well from RE native let's create it we're going to have header and this is going to be our header styles. header so what I want for the header there where is it go to account is to have the flex Direction row to put them in the same row and justify content space between so now they are just about the the the values and maybe I'm going to add pading vertical uh 20 maybe 10 and probably it should also have actually yeah I'm going to not do ping vertical I'm actually going to do ping so that they are line better and yeah I think that that should be good good for now um another thing that I'm going to do is I'm going to group this list together in a separate component that is going to be responsible for fetching the list and rendering the list so let's go ahead in the components and actually create a new component account accounts list. TSX so the account list is going to be export default function accounts list and it will return something like I'm going to use an empty tab and I'm going to put all of this free account list item here let's make sure to import account list item in this component and on our account screen itself I'm going to Simply render the account list not the item so this is going to be the whole list so now it works the same but I'm going to go back in the account list and instead of rendering it like this I want to render them as using a flat list because later on we are going to have a dynamic amount of uh accounts so we're going to use a flat list imported from react native to render them as a list so import flat list from react native and here actually instead of everything yeah let's let's start by rendering here a flat list and the flat list needs to things it needs data which should be an array and it needs a render item which should be a function that renders something what it will render it will render this list item so we don't longer need to render them separately and we no longer need this thing we're going to only have a flat list now we don't have anything there because our uh array is empty so if you're going to add a couple of manually like a couple of items we already see free account list items there later we're going to figure about figure out about the data because it's going to come from uh watermelon theb so I don't want to spend a lot of time here defining the data I'm just playing around to make sure that it looks nice the only thing is that we lost that Gap property between the items and we can get it back by sending to the flat list the style the content container style which is going to be the container that will wrap around all of our it items so if I add V Gap it's going to be added here so now we can scroll through this list uh I think we can also but I think it's good perfect so now we have our basic UI for our accounts so let's do get add get commit minus M um account UI accounts UI um and I think we're also going to need a way to add an account so to add an account most probably that's going to be a button below account list item so again at this moment my my goal is not to make everything look perfect my goal is to have it functional so I can move on on on using waterml NDB to make this application functional then at the end if I have time I'm going to overthink and make this uh look beautiful so for that reason like that's what I recommend you as well before making something beautiful make it functional so for that reason let's go ahead and continue and I will use a button component from R native inside our account screen from our application and below the list let's render a button called with a title add account so if I go to Accounts at the bottom we're going to have add account if I press on that one what should happen I don't know yet but I believe we're going to somehow instead of having a separate page for adding an account I'll rather add a simple line like this where we have editable [Music] Fields how to do it better I don't know again let's not overthink how to make it beautiful so let's go into the application accounts and here below the accounts list let's go ahead and create a view inside that view probably it can have the same style as the header and here we're going to have three text inputs we're going to have text input one and this text input imported from react native uh it's not visible but it's there so if I simply We'll add a placeholder here name we're going to see here name another text input with a placeholder cap percentage and another text input with a placeholder tap percentage so now we have three items there um I think instead of header let's do input which will have basically input row input row let's do the same as the header and add also a background color white okay so if I go ahead for the name here and add something it's going to push the other things on the screen so probably what we should do is add some styles for the text inputs as well input okay like this and let's give the input Flex one meaning that all of them will share exact amount of space in the upper container so if I'm going to go ahead and reload and go back to the accounts here the name yeah because it's not centered but yeah everything look it's okay it's good like the name is this then 21 this and then there should be a small button V are save or something like that maybe from uh XO icons save or check let's go with this one from En typo and this is is going to be at the end make sure to import en typo from Expo Vector icons so here we have an typo maybe 20 is going to be enough color green something like that so now I can do something like this and then if I'm going to press H this icon it should be saved okay we will be able to improve the a design now we we have something to work with the only thing that's left is to make sure that we um that we have access to the values of these text inputs we have access to what the user is writing because now if we press I don't like the icon I'm going to use like the button that we have here um so on press add account is going to be create calling a function called create account this is going to be a function that we have here const create account V for now we'll simply do a console war create account now if I press on this button we see create account but how do we get access to the values that the user is writing well for that we need a state variable and we need to assign it we need to bind it to our text input so let's go ahead and import use state from react and let's define the state of these three Fields the first one is new uh account name set new or should we do it as a as a separate component I think it's going to be better to do it as a separate component because it's going to make it a bit easier to manage so let's create a new in the components let's create here a new where it's going to be to yeah let me simply five names and leave it here for now let's do name set name and this is going to be a use State and the initial value is going to be empty string the same for cap set cap use state is going to be uh handled as a string because when we're typing that's a string and when we save it's going to be transformed to a number and the same for the tab set tab use State string now let's go ahead and assign this these State variables to the text input by providing two values to our text input first the value which is going to be our state variable for example name in this case and the second one is on change text which is a callback function that the text input is going to to call whenever the user writes something so what we want to do is we want to send there our setter this way we bind two-way we have a two-way binding to the text input by sending there the value and by updating it whenever the text inputs detects a change I'm going to copy it the same for the other two but make sure to to update them so the second one is cup set cup to set to now inside this create account function we can have access to this create account and then we can do name so if I'm going to go to the account write something in the name add account we have access to this value so we're going to be able to save it in watermel DB here perfect so we have the UI for adding a new account so get add get commit minus M add new account UI okay so with this account page I think we're done let's go ahead and do the same for the allocations you could create a function to delete the database what do you mean Vladimir is asking what do you think about 32 gigabyte M2 Pro is it Overkill well it's going to work well like if you have money go for it where you are from I'm originally from mova at the moment I'm based in Spain Tenerife uh look you know what I'm thinking I'm thinking that I'm thinking in order for us to get faster to the watermelon DB because as I said this was the focus of today's tutorial let's stop here with the UI because we already have something that will allow us to create and add something to the database and then something to read so let's try right now to go into the uh watermelon DB setup configure it create it a simple database only for our accounts be able to create and manage accounts and then later we're going to see how to add the different relationships the different models relationship between them for the allocations and this way I think it's going to be easier like and more like easier to follow so yeah I think that that would be a better approach not to uh for people that are only interested in water MB setup not to be bored with all of this UI stuff and later one if you are interested in following Until the End um I'll be very happy to to help you and to show you how I build this whole application with with allocations and so on so let's go ahead and see what's going get status make sure that we are have a clean uh git because now as I said we're going to start working on the watermelon DB setup and what rlb is um is a powerful local first database it's a database framework it's built on top of SQL light and it allows us to Lazy load data meaning that when we open the application it's not going to load everything there it's only going to load when we fetch this data so our application will launch much faster our queries will be much more performant because we don't load all the data in memory and it's going to work really well on even lowend devices that do not have a lot of memory uh so it's supports iOS Android Windows Web no GS it's optimized for react fast and yep and reactive so let's go ahead and check out the setup and let's start with the installation they do not have a guide how to install and set up in Expo so I'm going to adjust this guide specifically to Expo so the first step is going to be to install the watermelon be library in our application so I'm only going to copy the name of it and I'm going to go in our application let's go ahead open a terminal and let's use npx Expo install and then the package name Noby watermelon DB like this so npx Expo install is very similar to npm install or or yarn install the only difference is that Expo is going to check the version that is compatible with Expo so everything was added let's go back let's see the next steps we the next step is going to be to add the Babel plugin for decorators and this decorators will allow us to um to use these kind of decorations in our JavaScript and it will allow us to create the fields so so let's go ahead and install it simply using npm install DD bable plug-in decorators so I'm going to actually copy vpm command here I'm going to install it and in this case we don't really need npx Expo install because it's not something related to Expo but you can do that with npx Expo install it's not going to be a problem like it's going to be the same so now that we have this one let's see what do we have to do with it we need to add it to bable configuration as a plugin like this so let's copy the whole line plugins let's go in our application in Babel config and let's pre paste it below the presets if you have already the plugins make sure to add this line this line inside the plugins array now the next step is going to be configuring iOS um so we set up a pable and we will need to we need to do some changes on the Coco pods to link the watermel DB has a native dependency called CD Json which is provided for this knowled modules but it should be linked through the Pod file the thing is that we don't have access to the Pod file and uh later on we are going to generate the iOS directory and we are going to have that pod file but it's not recommended for us manually editing the Pod file when we're working with Expo this uh the idea is to always generate uh to the idea is to be able to generate the IOS and Android native projects based on only the configurations that we have here like in app. Json and this will ensure that uh this is what Expo is calling continuous native generation where we never manually update native files like the Pod file but we update them through Expo configuration files and through expon um config plugins uh this way we make sure that Expo can generate these files on the goal based on the configuration that we provide here so that means that to uh to apply this change that we have here that should be applied to the Pod file what we can use we can use the Expo properties if I'm not mistaken Expo build properties which is a config plugin that allows us to change configuration in the Pod file and gradel do properties in a way that Expo can apply these changes and this works with pre-build so let's go ahead and install this Expo build properties and now we will need to add this Expo build properties on under the plugins uh so the Expo bu where is it I think it's this one well if I go to up. Json under the plugins we have this Expo build properties it was added here but in order to provide more information like more configuration that we want to apply as build properties we need to put it inside an array where the first uh value is going to be the name and the second one is going to be the the options and the options that we want to change I have them here so let me quickly grab them so the option that I have here is for the iOS project I want some extra ports because from the documentation of watermelon DB we see that we need an extra pod called Sim D Json the name seemd Json this is the configuration like for what uh releases do we want so this is both for the debugging and release candidates uh here is the puff which was basically taken from here and then it also has this modular head header is through so basically you don't need to understand a lot here what you need to understand is with uh with the Expo build properties config plugin we are adjusting the Pod file in a way that Expo can understand and manage on its own not in a manual way in this scenario like we still stay inside an expo manage workflow even if later in a second we're going to create a custom development build so that should be the configuration for iOS um for Android I think I'm going to test it on iOS and then see what needs to be done on Android because maybe hopefully nothing should be done on Android so yeah now let's go ahead head and let's try to do a git status git ad git commit minus M install watermelon DB and now the next step is going to be to um create a a custom development client why because we need um we need some extra native code uh for the for the watermelon database so it's no longer being uh we it will no longer be able to run in expoo um we basically have to create our own version of Expo go that will contain the native code that we need that our dependencies need so for that uh what we can do is for this you actually need um in order to build it locally you actually need Android Studio to build the native side for Android and or X code to build it for iOS if you don't have them you can use yes to create a custom development build in Cloud so you can check Expo custom Dev client or development builds and you can see how you can get started using EAS build this is going to allow you to build build it in the cloud if you don't have you don't have environment set up locally in our case what we can do is we can do it locally by simply running npx Expo run iOS this uh will ask us first for the iOS bundle identifier let's press enter and what it's doing is it's creating the iOS native folder based on the configuration that we have here then it's installing the Coco pods I can even close the Expo go because that's going to be a separate application it's going to take a bit of time until it runs hello miar Jade thank you very much uh elos send send me an uh a message on Discord I'm going to try to to check it out is it possible to deploy the r native application to the App Store of course we have some tutorials on that on the channel check out the deployment like we have tutorial how to deploy it on Play Store how to deploy it on app store all of them Lan is asking please can you do a hackathon that's a that's the second time that I hear this request today uh so let me know if you're interested interested in a hack aone uh because we are running every year we are running with not just hack and this year it's still upcoming and I'm not sure if I'm going to um we're going to to we're going to organize it in the next couple of months because right now I'm working on a huge new course uh new Rec native course uh let me show you some stuff where is it Miro is my internet connection okay or am I lagging yeah I'm working on a huge uh course that will contain eight different separate uh projects and it's going to teach you everything about react native and Expo from the fundamentals all the way to the advanced topics so this is taking a lot of time and this is my main focus these days and hopefully we're going to have something public um at least a wait list in a couple of weeks so if you're interested uh pay attention to the channel and to to social media you can follow me on Twitter but the hackathon is something that I'm really interested in so it's going to come this year so what's going on there with our application actually it's still building yeah native side projects are taking time so that's why I actually love working with expoo but sometimes we have to um build our own build but the thing is that we need to do it very rarely like after we create this build uh we will have to recreate it only when installing some native libraries if we're simply installing some JavaScript libraries where if we are editing our components we don't have to rebuild everything we simply use the same build and continue working after that build we see that it's start it's opening on uh our emulator we see opening profit first and this is a separate application besides Expo go that is specifically dedicated for our custom application here so it opens it works the same way but now it's not the expoo it's our custom development build and the same is going to work for Android if you do npx expo Expo run Android I'm going to start the build here in the background it's also asking for Android package let's go with this one uh I'm going to have like the build in the background so it's going to be ready for later uh but we're going to move on with our uh watermelon to be set up so um let's do the following let's do git status so we see that if if we do git status we have a two new folders Android and iOS these are the native side folders by default um like they like they will be tracked in your Source repository the idea is that uh Expo is trying to push towards uh continuous native generation which basically means that this directory should never be in your Source repository this directory should be generated using pre-build like always on the Fly uh in in a way so that we never manually update them so for CNG for continuous native generation two rules one is to open git ignore and add our IOS and Android folder here and now if I do get status we are not going to be tracked and the second one is to never manually update the IOS and Android folder and always generate them okay now I can do G ad G CIT minus M Uh custom or development build and we can move on so going back to our watermelon DB installation I think we should be done hopefully later on when using it we're not going to have any issues but let's go ahead in the next page under the setup and we're going to set up our application for watermelon to be so the first step is to create a schema in our project where we will Define how our tables and what data we're going to have in our database I'm actually not going to create it under the model because I want to keep only the models under the model so inside the source let's create a new folder called DB this is where we're going to have database files let's create a new file schema. TS and here let's bring this code it creates an up schema using from watermelon DB it sets sub version and later we're going to add here tables let's go back continue uh the next step is the migrations I'm also going to create them under our database as migrations dots and let's copy the code from here and paste it under migrations we're going to talk a bit later about migrations but this is basically uh the logic of migrating your data database from a version to another one for example if you're going to rename a property or if you're going to add a new property you want to have some logic of how should I take a old database structure and move it to a new database structure this is what migration will be used for now let's go back and continue oh sorry um let's go ahead and this is going to be our our file where we're going to actually set our database so let's call it the index file because we are inside the database folder so the index is going to be our database itself so let's copy this code from the documentation let's paste it here and let's adjust a little bit our Imports for example our schema is also in this folder so I'm going to remove a model from here um and what it's happening here is is creating an SQL light adapter a way for watermelon DB to connect to SQL light because behind the scenes uh watermelon DB is using SQL light it's specifying the schema that we imported using the migrations um optionally you can provide the database name but we don't need it provide them using the GSI and then and only then it's creating the actual database using the adapter that we set up here and using the models that we're going to Define in a moment so far a bit of boiler plate but uh we're we're we're going through it this is for for the web uh we're not going to cover it now we can check it a bit later so that means that we are at the end of this page we can go next to the schema so the schema is um the database schema is the definition of our tables and the columns that they will have sqlite is a relational database it's a where we have tables and every table has different columns or Fields so defining a schema we uh do that in our schema. TSX folder using the table schema function like this so let's copy for example the table schema the first one that we see here and adjust it to our needs let's go to the schema itself let's paste it here under the tables table schema the name post title subtitle and so on but actually I'm going to adjust it based on our specific application and before that like if you're working in a different application I'd recommend you to do the some diagrams of what tables you're going to need in the relationships between them I already have done that before the live stream so I'm going to start with a table called account and an account has if we look in the UI name cap and tab so ID name tap cap then uh we're going to think about like the others but let's now Focus only on this account so uh we don't specify ID because this is a field that watermelon DB will automatically add but instead of a title or let's start with a name this is going to be instead of posts it's going to be accounts the table names try to keep them plural with lower case and columns is going to be instead of title we're going to have a name of our account of type string then we have two things tap and cap we're not going to be yeah let's add some space here and let's add the name of a column current allocation percentage and this should be a number I think right yes yes booing number and string because we are using typescript we have nice suggestions there and the same should go for our top the type should be number and we don't need the other ones so I think I can remove them uh any of them should be optional name cap and tap I don't think think we need them to be required so I'm going to leave them like this okay so that's uh our table schema where we have only one table for the accounts we're keeping it simple to at least see something working and then we're going to slowly add more tables let's go back to the documentation of watermelon and see the next things yeah string number and Boolean for the column types for the special columns the ID is automatic Ally uh assign for us automatically and there is also some other fields that we should never uh add ourself like status and changed but we can add special created that and updated that if we add them watermelon DB will automatically handle it for for us we're going to see later when we need it okay okay okay let's go to the next step The Next Step is the models so the models is a way like a model represents a type of a thing in your application for example all of our tables like account allocation alloca account allocation these are going to be different models they will specify where Fields where relationships and using them we're going to be able to fetch create and interact with our database in a easy way so let's go ahead and start by creating a new folder where we're going to keep all our models it's called model and the first model is going to be account. TS so let's see it based on um document based on this example I'm going to copy this and I'm going to add it to my account model we import the model we Define it let's rename it from Post to account it extends the class model and it specifies the table name the table name should match the one that we said here in schema so in this case accounts so let's put accounts now yeah this is the table name that we Define in the schema now we need to add the new model to our database let's go to our database which we Define in the index. TSX and here in the model class we need to add the uh our model so let's first import account from one uh folder up model account and let's use this account inside the model classes here we Show an example with this post which I no longer need so I'll remove the comments okay that's our database uh associations we're going to cover them later and now let's talk about the fields to create the fields we need to use these decorators and these decorators will allow us to Define and Link a Class Property to a column in our database so for that we're going to need to import this field and text for example decorators in our model account and then fields are what's the difference between field and text to be the same type string number as we column type for a field that contain arbitrary text specified by the user use text a simple extension of a field okay so text is an extension of a field that also trims white spaces okay so for the if we look in the schema of account we have a name field of type string so let's use here uh the text decorator let's target the column name the column name that we specify on the database layer in the schema name and now we can Define here the property name which can be anything in our case uh but it would be better to have it named the same thing and I think we also need to specify the type string it doesn't show where but I'm going to specify because I'm using typescript where are not and I think actually I don't have to because I'm probably it's going to understand that it's um it's a it's a string but later we're going to check so we have a text field for the name we have two more for the cap and tap I think in that case we're going to use of the simple field because the text is for text but in our case we need numbers so at field cap is going to be a property called CAP and then add field tap is going to be tab okay before we move forward we have these errors unable to resolve signature of property decorators that's because of our uh TS config file in the compile options let's add here the how is it called experimental decorators true so if I add this and go back to the model now this property uh is working and will it understand that this is a string no it doesn't so I think I would rather type it myself like string this is a number and this is a number now it has a property okay so we defined the fields let's see what's next uh custom queries I don't think we need anything for now let's go to the next step migration migrations we're not going to do them now yeah I don't think we're going to do them now and let's actually go to the next step usage let's see relations we don't have any relations yet we're going to cover them a bit later let's check how to actually create read update delete So reading first things first we need to get access to a collection reading where are we going to do the reading let's try a very naive way of going on our where um on our accounts so application maybe in the yeah let's go in the account let's go in the not allocations account let's add a simple button here um read on press on red I'm going to add this button it should appear somewhere under the accounts after adding this const on read console waren read come on can it connect what's going on oh I don't have a server running so and for Android it fail to install oh my Android doesn't have enough space anyway I'm going to go uh back to one of the terminal I'm going to do clear and I'm going to do npm npm start this will start with the project but it's saying that it's using still Expo it's using Expo go so by simply pressing s it's going to say using development build and now I will be able to load here and it will connect with the server and use it we can also change here in the package the Json Expo start I think it's Dev client if I'm not mistaken and this will automatically start it with Dev client uh so if I go to accounts I have this read button that I will use to interact with our database and see some crude operations Reading Writing uh and so one so let's go to our accounts here in the read what I need is I need to get access to our collection or to our um table so this is how it works for for getting access to the post collection in our case we want not to the postl collection but to the account table and we this is going to be called accounts collection but for that we need access to the database the database that we have in the DB index here the thing is that we need to export this database from this file to be able to access it so let's do export default database now from our account if I'm going to do command dot it's going to suggest us to import database from DB folder which is our database that we created here so we have accounts collection what we can do next is find the record by ID we're not going to find anything probably uh but we can try try to write something first modifying the database so to modify the database we're going to need a writer so let's copy this code and adjust it to our needs so first of all our function should become a sync now because we have that a weight database right so all the changes should be put into a database. write which is a method for starting a transaction I explain this concept of transactions in the previous uh tutorial but what that basically means is in a transaction we can have multiple operations like multiple insert delete operations and it's either all of them will pass and successfully or if one of them fails they'll be rolled back so none of them will be applied this is great to keep everything consistent and if we have for example in a case of change sending money from one account to another you want to have two operations first remove uh decrease the money from one account and then increase it to an to to the second account so if there will be an error between these two operations you don't want to to to write this corrupted information to the database because you're going to either have more money uh at the end or less money depending on the order you want either both both of these operations to pass or if one of them fails to revert back to the initial one so that's what database. is doing it's starting a um a transaction so in this case I don't need the update so actually I'm going to remove everything inside I'm going to check how to create a new record so it's going to be our collection do create post okay A bit weird documentation but it's going to be our collection do create and this create will have will give us the account Builder from where we can do account. name right I believe so test uh and then account dot cap let's say equal to 1050 and account. tab equal to and not like this but as a number 20.1 something like that uh do create and it should also be a weight here let's give it a try let's this is supposed to start the transaction and create a new account with this data let's try to press read which is actually not read but it's just test I should name it test and what was happening there did it show us possible and handle promise rejection why because cannot read property type of undefined from column column schema something wrong with my schema let's check the schema type type columns did we add it where we need it schema migrations index model oh it's not tab but tab save test we don't have an error which means that most probably it worked in order to test if it worked what we can do is I will comment out this code and instead I'm going to fetch the accounts so accounts equal await we're going to get the accounts collection dot do what dot let's see how to fetch it uh query query. fetch do query. fetch and I'm going to do a console log account so if I look in the logs and press test we see something we see we see something not sure what we see there uh do query. fetch query. fetch let's try again to press on the test and yeah um V this was coming from yeah I had to to restart it but now we see the name is test top is this Val value C is this value so our writing and reading has actually worked correctly okay uh so that means that at least our configuration has been um has been done correctly uh H database yeah at least our configuration is done correctly and now we're going to think how to actually implement it in our application to properly work with it so here what I don't like is that uh account doesn't understand what type of model it is I think we can specify this if we provide here database model account from the model so account collection now it understands the top the cup and so on and if I'm would make a mistake like this is going to say it no cap is actually a string so now everything is correctly typed um I think that another another thing that I would like to do is I would like to create some kind of shortcuts towards this collection because I don't want to always have to do accounts collection get accounts and so on I would do it how where I would do it database in the index colle collections models would I do it in the model and Export here the account collection h or maybe here from DB yeah let's export here export uh let's do [Music] account account equal to to database. getet and so on can I do that now if from our page I'm going to import here not database but accounts will I be able to use simply accounts or should I name it accounts collection but it's too long accounts collection uh how do you name it accounts collection let's name it accounts collection so let's import accounts collection from DB and now we no longer need to find it like this so if I do test it adds it works as it was working before but it's much easier when share between our files okay good let's go ahead and do um get status get OD get commit uh install and configure watermelon DB for my Android I think the problem is something with um not enough storage so let me try meanwhile to delete some of the stuff from there have a lot of applications there for testing just one sec second which one and also meanwhile I'm doing that let me do again npx Expo run Android to make sure that it works on Android as well I'm just deleting some of the old applications from here oh no it was it was running it was running okay okay so far so good have space it's loading first of all it build it's loading hopefully it's going to work please because if it's not like it's very hard to debug these errors we see what JSI SQL adapter not available falling back to as synchronous operations it will happen if you're using remote debugger and may happen if you forgot to recompile Native up after watermelon DB update what will that mean for us if I go to the account and do test and check with the logs and if I do test again the first time yes it's reading correctly it's writing correctly but will it persist which means if I close the application come on go away go away and if I open it again profit first I expect the data to be persisted because it's a local database so if I do test yeah it's persisted so I'm sure what was that error warning because if I reload I don't get it no I get it we're going to see if that's some uh to synchronous operations GSI um yeah in the database configuration index not here in database index there is just true which has a comment like set it to True only on OS and they are explaining it like this recommended options should work flawlessly out of a box on iOS on Android additional installation steps have to be taken disable if you run into issues disable if you run into issues but I don't run into issues yet so if you run into issues go ahead and disable it by and commenting this part and using JSI only on iOS but I'm going to keep it like this until I run into issues so yeah uh again as I said the benefit is that now like this is not like in memory database which will be lost like when we relaunch application this is a local database that will persist after closing and opening web application if we uninstall the application like the data is here but if we uninstall the application in that case uh we are going to lose the data so again this is not a remote database it's a local database that lives on your device and will work even without internet connection I'm very happy that actually it works on Android as well uh and meanwhile I'm going to test it to make sure that we keep we keep everything working on both Android and iOS and maybe even later on web as well but for now we are good with a basic configuration we don't have anything in the G status and we can move on to um to implement and connect it with our UI components to properly work with it and not by these testings and later on add different tables run migrations connect everything so it's a lot of fun coming up your way uh with we are still halfway through this tutorial and hope you're enjoying it so far if you do make sure to press the like button below subscribe to the channel That helps us a lot oh lot of comments let me check now application related to AIML in future we have some uh Integrations with open AI tutorial on the channel is thisen up with local database I am late uh so didn't get it in the planning to watch it later so yes exactly this is an application with a local database for the local database we are we are using watermelon DB which works on top of SQL light so at this moment we have set up configured and it's working now it's time to integrate it for all our crude operations hi guys am I late um we are in the middle of a tutorial but um this tutorial will be uh published on the channel so you can always go back and follow it from the beginning but you can you can stay here uh now and uh see the next steps what we're doing here no additional configuration needed for Android well I don't know for me it works uh so hopefully no but I can go into the installation guide here and let's see what some manual Integrations were meant for for Android that we didn't take so linking manually yeah like we don't need linking banally because it links automatically yeah this is definitely something that we don't need to to cover using with react native screens and react native gure Handler we have react native screens but we didn't have any issues with it it says that if you're using recent versions of reative screens for just your Handler you'll need to set the cotlin version to 1.5 20 or above csection above which section above anyway like if you need this you can do it through the build properties uh C no C clean version like look there is for build properties the same way as we configured uh in ABDO Json using build properties same way as we did for iOS we can do that for Android and we can do I think come on Co no cotlin version but it's part of what it's part of plug-in config type Android so let's see where it is you M packaging options uh pluging Ty Android packaging no compile Target build Android it's this one plugin config okay build tools compile enable okayer manifest queries again there was cotland version part of what part of part of simple Android so it should be here cotlin version and then you specify what was written here in the documentation one 1.5.2 or above I'm not going to actually do it because it works for me so I'm just showing you uh this is the part that that we might need the GSA install installation because we saw some warnings on Android that if I reload come on come on reload I'm going to comment out this word even where is it here reload we see this GSL warning that was not installed so let's see if we can do that to enable fast highly performing synchronous GSI operations on Android you need to take a few additional steps make sure you have ndk installed in Android settings. Gradle include the watermelon dgsi oh I don't think I'm going to be able to to do that so the thing is that yeah so far it's working for this I would actually look uh I think that [Music] Morrow watermelon config plugin I saw a buil in like a a a separate config plugin created by Morrow for watermelon DB I didn't test but maybe it's going to be uh the adjustment that you need on Android yeah GSI support for Android this plugin installs automatically GSI support for Android build as per V documentation so I'm not going to do that because anyway it's working so I don't want to risk like breaking it completely maybe at the end like we we can try to to set it up like this so we're moving on uh let's go ahead uh and actually I'm going to grab quickly a coffee and we're going to power through the next steps uh the next step is going to be to actually uh connect our UI to uh water B to add and read and fetch and automatically update when something is happening so stay tuned we're going to continue shortly e e all right guys okay I think I also need some fresh air so let me open the window and we are ready to continue so the things that we have we are doing in our uh not allocations but accounts page uh here on the database right that's actually something that we have to do in create account so let's copy this from here and add it in our create account method we're going to need to make this method a sync a sync so what we are doing here is for the name we're going to take it from our state for the cap we're going to try to take it from here but you're going to see that we cannot assign a uh string which is our state to a number here so we're going to parse it with number parse float we're going to parse that string and the same thing for the top number do par float top now if I'm going to try to do hello 1.21 1.5 and press add account uh and then if I'm going to go ahead and do test which will fetch and log the account which I can actually add them to adjacent do stringify with some parameters like null and then two to show to to display them better so if I press test now no doesn't want to stringify because account is doesn't want to stringify accounts that's weird but anyway because it's an array of objects H not a Json okay but anyway we should have if I search here hello we see name hello tap 1.6 cap 1.2 that's exactly what we wrote here in the input so now we are correctly writing to our database our uh new thing what I want to do after I write to the database so after the write I want to reset this Fields by doing set name to nothing set cap to nothing and set tap to nothing so if I press once again it's going to reset them here perfect now with this on read actually shouldn't be it shouldn't happen here and also it shouldn't happen on button press it most probably should happen with a use effect um when we launch the where is that account list component so there is the account list which is the component uh responsible for rendering the list of accounts so let's try it with a usual way which I'm used to and then I'm going to show you a different way where actually the the right way of fetching data with watermelon DB so usually how it happens is we have a state variable for example const accounts set accounts I use state is going to be empty uh empty array and then inside the use effect when we Mount this component what we are doing is we need empty dependencies here here to run the use effect when we Mount the component here we need to create a function fetch account which is going to be an a sync function and right away call fetch accounts now fetching the accounts we saw previously how it's done here using this on read so let's copy it uh accounts collection should be imported from the database and instead of console logging accounts we are going to uh we are going to set them in state so set accounts accounts now let's try to use this accounts in our or let's try to at least console log accounts and if I go to this page use state is not defined because we need to import it from react and if I'm going to go here we should automatically see the array of accounts now we can take these accounts and use them in the as the data in our flat list and we should already see a lot more accounts and if I'm going to do here add account I'm not sure if it will work without cap and tap but the thing is that it doesn't update automatically so we see that now we have 1 2 3 4 5 six but if I'm going to refresh the application come on why it's not refreshing reload and go here it's 1 2 3 4 5 6 7 8 so now we see that it was actually added but we were not observing the changes and that's going to be the main difference of fetching it like this and observing the queries or in a way subscribing to updates uh before I actually before we actually handle the obser observing and handling these updates what I want to do is I want to send the account that we are rendering to this component because at the moment all of them are hand displaying some dummy data and to do that let's go ahead and receive the item that we are currently rendering which is of type should be of type accounts we can type this one as account array account from the model and now account is account and this one is account okay and we can send it here as account equal item now this way we are sending a down to our component a property called account with the value of one of this account from our database now we're going to receive this property on the account list item through the properties here using the same name so account if we want to define the type to have better type typings we can create a type with the same name of our function it doesn't have to be the same name but it's cool that we can use the same name and specify that it has an account property of type account imported from model from our models and the last step is to assign here specify that this property object is of type account list item now I can take account here and instead of a profit I can send I can display account. name instead of 10 I can render account Dot cap is for yeah first is cap and then I can render account. tap so just like that we have this account test test test hello one two three and so on if I'm going to add here uh new with one two two 4 add account and then reload the application go here to the counts we see it at the bottom new 1223 exactly what we wrote in the input ah with the Styles we're going to figure it out a bit later now it's not that that important uh what's more important is uh to handle I'm going to remove it here and from our accounts page I will remove this test button because we no longer need it we will we are actually implementing it on our UI so I don't need this functionality anymore so let's go ahead and uh commit these changes get add get K me minus M Fetch and render account Fetch and render accounts so we are currently at the components account list here where we are fetching and rendering the accounts so for so good can you use decorators actually I'm using decorators for the field uh if I check the model here on the count I'm using the decorator for the fields and probably you're asking me if I can use the writer um the writer decorator so I'm going to show that uh in a moment as well let me take a note here uh right writer decorator so I'm going to show that and explain how it works as well oh okay okay okay moving on moving on uh what I want you to to do next is going to be around observability because the problem is that yes we are adding new accounts but our account list is not subscribing to new changes um so let's check here connecting components connecting components is how we can connect data to our components and uh let's check how we can do that yes connecting components is working using higher worder components higher worder components where think of a past like nowadays I don't see them used very often but in water m&b there is a particular reason why we're using it and I think we're explaining somewhere in the documentation so yeah um how it works is having a normal component that will receive a uh a um an entity where the data of for example a comment this comment can be fetched sent here but the problem is that it's not reactive meaning if the comment changes the UI is not going to render if the comment is updated or deleted the comment will not reender to reflect the changes unless an update is forced manually or the paring component re renders so in order to enhance this component uh to make it observe a comment automatically what we are doing is we are using this with observable from watermelon DB react and we are using uh we are creating a higher order component using this weave observable that is being used by wrapping around our normal component and then exporting the enhanced component so let's take it step by step uh what do we have to do so account account lists this is our normal component we need to create a enhanced component to do that we first need the to import with observable observable from Noby watermel DB slash what was that uh Slash react like this now at the end of this file we're going to create the enhance higher word component using the with observable here the first parameter is something similar to how the dependency array Works in a use effect which will say like update whenever these things are updating or whenever these columns are updated then we're going to receive the default parameters and because by default we didn't have any props in our component we're not going to have any props here either and then we are going to return we need to return an object with new properties that will be sent down to this component for example instead of fetching them here I'm going to send down to this component the accounts that it needs to render this account will be fetched here when in the weave observable so account is going to be a weight like not a weight probably I don't think it's a weight or maybe I don't know let's see it like this accounts collection. query let me let me double check if that's correct datab do query yeah do query yep yep yep yep yep so now using V hence we can wrap around this accounts list I made a mistake probably observable with oh with observables plural now this enhance we we create an in enhanced component or enhanced account list by simply wrapping it around our account list but make sure not to export our account list so I'm going to remove export default from here but instead export this this enhanced account list so just like that if I go to the accounts I should see exactly this even though we do not fetch anything here we fetch them in them observables and I hope observe question mark one and one add account yes and I hope that this query is already uh an observable query which means that whenever the accounts are changed like added or deleted or updated it's going to um render our account it's going to refetch and render our account list here so now we no longer need to use use effects or state we're going to receive them for here which can also be typed as accounts of type account array right and to make things a bit easier to understand [Music] I don't think like we need like two lines here because here we Define and here we export I think we can simply export this enhanced account list I was just showing how to to do it and like it might make it a bit more confusing but I would combine these two codes as well by not creating a in ened component but by using with observable and then at the end calling it with the account list here and Export default like this so it will still work but might be a bit confusing like why why that is happening so probably I'm going to go back to having defining this enhance function and then wrapping it around our component so I really hope that this is not too uh confusing as we move like uh in this uh tutorial like we're going to talk more about that and learn like the intricacy like how how everything is working but actually what's happening here behind the scenes that um what we don't see is on this query it's actually calling the dot observe and I can do that manually and it's still going to work but in the W observable it will automatically call it so it's a shortcut to that so there the difference between the fetch which will request and that's it and that do observe which will subscribe to updates so we could actually also use this with observe inside a component uh Define this observable then clean it but I think like with this with observable it's much easier because it handles all of this Logic for us like cleaning U um uh unsubscribing subscribing back and making sure that it's optimized for uh for this re rendering okay so this was our reactive lists and as you can see like it's everything that we put here it's a shortcut to that dot observe later we're going to also talk about reactive relationships counters maybe oh here they are explaining why not using react hooks there is a discussion here so in a way you can actually use the hook but I think they are saying that it's more performant with uh with this with higher water components for okay there is a lot of advanced stuff here we can get the database from there no I'm good okay okay okay so this was uh G status get add get comit observe lists I'm wondering about um one thing which if I update one of the items in the list will it update in the list so for example to test that what I'm going to do is let's go into the application accounts and here add a new button again for testing purposes title uh test update on press on test let's try to implement this const on test equal it's going to be an sync function and it's going to new a wait database. write here a call back function and it's going to update something uh let's see create update logic modifying comment await comment find comment ID h maybe I can yeah let's uh I don't know get all the accounts using a wait uh accounts collection dot query do F Fetch and then I want to update the first account con account equal Accounts at position zero taking the first account and I want to update it using account. update updated account I want this updated account name to be equal to one so if I go here and press press test update I expect the first account name to be one it's not but if I reload the application let's try reloading the application and going back to account it was updated so what does that mean that means that the component account list item receives the item but it's not reactive it doesn't react to changes yes our whole list is reactive and whenever we do something and press add count it's going to change because the the query on the whole list is reactive but the specific item and changes to that icon are not reactive so if I do here to and press test update it's not reactive it needs a Reload so how do we make the component account list item that is rendering One account reactive as well to do that uh we're going to implement the same logic with observable so let's go to the account list item let's import with observables from waterml nb. react react we're not going to export default V function however we are going to create a enhance function using the we observables and here where as we saw saw before it was something like this where we didn't receive any properties and we return return something like that's in account list we didn't receive anything but we gave down to the account list our accounts the think is that this when using this component we are going to receive the actual account and what we want to do is simply give it back here which in fact is going to do account. observe so this would be much um much more correct account. observe m but I think we need to to destructure it I think we need to destructure it like this so now we're going to export default enhance and we're going to enhance our account list item so the thing that we are exporting and using inside the list will receive the account but it will take that account and will add one extra step it will do an observe on that account and give here an observable account so now if I go here and if on that testing screen I change here to free and press test update we see it instantly updating here if I do back one and do test update come on test update we see instantly one so now this list item is adding the observable around the account that it's it's receiving and the thing is as I said the observe this this observe can be omitted because it's automatically added and because it has the same name it can even be shortened like this okay uh I think should we with observable account any should I do it like this how to to give the the type there expected to argument but go one oh and another thing is that we need to add here in this parameters the name of this account in order to update the observable whenever we receive a different account that's also important similar to how a use effect works but here we just specify what of these properties have to resubscribe to new updates so if sending a new account to this component we need to resubscribe and not keep all subscription uh it's any I don't really like any here because in the list it's not going to ask us to send anything so I don't really like that I might do here count list item like this and now it will enforce it let's check with observable typing typ script Bing exposer help observable oh my God props offer and post oh boy okay this is input props uh I'm not sure I I will leave it like this it knows that it's an account count one still kind of works so doesn't have proper type definition there but anyway if I do test update it subscribe to these changes if we're going to do the updates from a different place in our application so I don't longer need the one test and the button now our account list item is also uh observable and updating automatically when the account that it renders updates somewhere else in the application so get status get add G commit minus M observe uh account list item that's it okay thank you very much mean and foren hello Don so let's move on let's move on because we we still have some stuff to to handle I'm not going to cover Focus too much on the UI I think uh we are good here maybe we want to add a delete method so that we can clean up a bit of this stuff so yeah let's try by simply adding um um a delete icon uh Delete I'm going to do it like this uh again it can be improved later but now I think it's good so I will do import and design and I will render with delete item inside each account list item at the end so something like this gray oh it looks bad but I will I will keep keep going like this maybe I can do Flex one on the name and then Flex one on the percentage to make sure that they take the same amount of space like this and it at least will be aligned and then the delete icon will be at the end so this is going to be the const on delete it's going to be a function that will be called when we press on this button so on press on delete 24 is too much so maybe 18 okay that's better and what what do we do in the one delete let's check how to delete an item using uh watermelon DB so in the create read update delete let's check delete a record so we just take for and we either destroy permanently or we mark it as deleted which is also allow us to synchronize with a cloud so I think it's better to already use Mark as deleted because if later we're going to synchronize with a cloud this is going to allow this to happen in the cloud as well so I think it's simply account. Markus deleted and that's it let's try it with the last account 12 if I press I don't know what's happening possible rejection Market deleted can only be called from inside of a writer yes because I need uh uh database. write and here Mark as deleted is not assignable to a sync yes and this is promise so I need a weight here and probably I need a weight here which needs this function to become a sync once so let's let's try it again if I press it works and it automatically updates just because our list is uh is an enhanced list that observe the changes so it will observe both adding new stuff and removing stuff as well so now we saw how to delete and we actually saw how to update as well in the previous step when we were testing so that was our G add G commit minus m delete account perfect perfect perfect perfect I don't didn't even realize when I uh finished my coffee when I drank my coffee I think it's time to to move to the allocations to move to the allocations and for that we're going to add new models in our database schema and we're also going to learn about relationships between models so the as I said allocation just to reme remind the definition of allocation is the process of sending Mone money from the income account to all the small plates so it usually happens like based on the book it uh happens twice a month on 10th and 24th of the month so inside one allocation we're going to have multiple account allocations so for example on 10th we create one allocation with that date we specify how much income we had and then for each account in our in our profile for each account that we Define we're going to specify the how much allocation should happen for that specific account during this allocation so think about this is as just specifying the date or a group of allocations and this as every single line based on how many accounts do we have prob probably on the UI it's also going to be easier so when we add the allocation we specify the income it automatically calculates us the value based on the percentages that we have set and here when we render it we see that this whole component is one allocation and every line below it is going to be one account allocation this way we have like a many to many relationship between accounts and allocations because inside one allocation we allocate for multiple accounts at the same time so that's why we need this intermediate uh table so let's go ahead and Define [Music] them I think we need some kind of UI first so I'm going to start with a new allocation page as we have here in our mock the new allocation will have only one input for our income and it will calculate the our profit owner tax and opix so that means that um that inside our application allocation new we are going to have the following form let's right away play with stylesheet and move from rendering to styling at the same time just to make sure that we manage in time everything create we're going to have a container for the whole page we're going to have probably a label we're going to probably have an input and we'll see what else we have so let's define here styles. container and the container will it's okay now we need the income with an input so it's going to be text style styles. label input not input but income income and that income uh is going to be let's say below it we need a text input so text input from react native the place holder for this input is going to be something like this one two three okay let's add some pting to our whole container 10 um the label font weight Bal maybe we need to put them in the same line I don't know for the input I'm going to use a background color white background color white but I didn't assign Here style styles. input uh ping 10 border radius 10 or maybe five okay let's put them inside The View with a style row input row input row not even sure if I want to put them in a row but let's try Flex Direction row and then our input is going to have Flex one to take all the available space okay and the input row will also have line items Center and here I have two commas to make sure that they in the they are both aligned and let's add a gap here to make sure we have some spacing between the that one and but the label will let's give it a wave of 100 pixels to be fixed now below it we're going to have all the all the accounts but we're going to cover them in a moment let's only um let's start by handling this allocation because if we look in the table the allocation itself it only has the date and the income so let's save this thing let's define the table let's save it when we press save here and then we're going to add the distribution between accounts let's say so uh there are a couple of last things that we still need here for example the the field in income State and set income use State initially is going to be empty string let's assign it to this text input as value equal income and then set income not set income but on change text we're going to update our state variable so to be able to keep it in state now at the bottom of the screen probably we're going to have a button uh on press is going to do save and the title of this button is going to be save let's define it here con save equal it's probably going to be an a sync function that later will write to database so if I go here and press new allocation and then press save nothing happens but this function is going to be called uh on the yeah for now for now it's good maybe on the container itself we can add here a gap of 10 to make sure that we add some spacing between the input row and the button okay okay okay uh so this is the UI for our new allocation let's go ahead and cover the waterml DB part and for that we need to set up a new table in our database and create a new model that will allow us to interact with a data Veer so we need um we need a new schema in I mean we we're going to start with changing the schema inside our database schema and the same way as we created the table schema for our accounts we're going to create a new one below using table schema the name of a table is going to be allocations it should be plural and the columns should be ID we don't specify it automatically will be mentioned so the name of the what else we need that date where better instead of calling it date of type date we can maybe use a predefined field from watermelon called created at in the schema uh special columns you can add special created at and updated at columns to enable automated create update tracking and by adding them by having this created that we are not going to have to specify it water MB automatically will uh take the current time stamp and write it in the created ad when we write something and the type of it should be um what's the type of it if I check here it should be number so it should be number okay that's the first the second one is going to be name if I look in our plan we have income we need to know during that allocation how much income did we receive and did we distribute between different accounts so the type is also going to be a number okay now that we have a table schema uh it's going to automatically be added to our our database because we are specifying the schema here we the next step is going to be to go into the model and create the model for and the allocation dots it's going to work similar to our account so let me actually copy paste it because I'm lazy change the name of a class from account to allocation table name should be the same as the one in our schema called allocations and for the fields we're going to have uh we're going to have well we're going to have a number field called income let's call the field also income and I think we're going to also have a field let's see how we can do what we should do with created that in the model definition we created that is read only date created at so let's do it like this read only and the read only should be imported from the decorators let's import it here we don't need the text at the moment but we need a date decorator so now it has been created that field as well and here is where why we need to specify the income twice the thing is that on the database layer there are different um best practices in terms of naming for example um we need to use the underscores like the snake case in our JavaScript code like the the best practice is to use camel case so that's a benefit of having to specify them twice and another benefit is that if we update something if we want to change from income to Revenue we can do that here in our application code but we can leave on the database to be income so that our application is Backward Compatible and works with previous versions as well so I'm going to keep it like this okay so we have allocation okay okay okay um I think from the database index the same way as we did account collection let's do the a Lo ation collection as database. getet a loation and here we need to specify the table allocations the same name as we used in the schema so using this allocations create collection we can go in our in our file application new on this new new screen and when we press save what we can do is we can start with a database. write to start them to start the transaction and here we're going to do allocation. collection. create new allocation and here we're going to specify what the new allocation dot income is equal to the income that the user set here but we also need to parse it to number so number. par float going to be to this income we don't set V created that in VI ID because they will automatically be generated by by watermelon GB so let's give it a try and let's write here an allocation 1 2 3 4 save and handle promise rejection cannot read property create war of null because allocation is coming from there did they M the schema oh I think I know why I think that the schema was not migrated so let me check the schema double check if the name here is the same yeah I think is the same uh and if I reload the application it should show a warning does it show a warning uh this is from new allocation one two three save yeah I think that it didn't run the migration so let's check how that would happen uh in the usage connecting quering Rider create setup migrations the migration is the mechanism by which you can add new tables columns to the database in a Backward Compatible way without migration if a user of your up upgrades from one version to another their local database will be cleared at lounge and they will lose all their data always use migrations Pro in development you can skip them but in production always use migrations without them users will lose their data so let's see how we can add a migration hook up migrations to the database adapter we did that migration is workflow when you make schema changes when you use migrations be sure to do this in the specific order to minimize the likelihood of making an error first we need to add a new migration first Define the migration that is Define the change that occurs between two versions of a schema such as adding a new table or a new table column don't change the schema file yet what I already did I don't really want to to to write another scheme like it looks like I have to do a lot of things like I have to write schema I have to write model now I have to write the same like for migrations which understand why it's happening but in development I think it's it can be easier when you're not using migration the database will reset delete all the contents whenever you change the schema version if a migration fail with okay let's try to manually change the without a migration now uh just to to skip it for a second because we're still in development let's go to the index or to the schema and change the version here from one to two missing migration um and can I um I think I'm going to just simply yeah as we are writing here you might want to comment it out for develop purposes because if we don't specify migrations the database will be reset so now after I change the schema version to two if I will go to accounts I don't have any accounts because my uh database was reset uh so this is okay like in development but in production we need to write migrations but I was wanting to try the allocations so one two three save it's still possible and handle rejection canot read property create of null am I doing the create wrong but create of null that means that allocation collection is null let's check on how we are adding a new account do create from DB allocations allocations allocations locations oh I forgot to add the model class here so after creating the model we need to put it in the database so let's do here uh location and right now save we don't have any promis rejection which means that it works okay so yeah another thing that we need to remember to do so one thing we need to define the schema second one we need to create a model third one we need to add the model to our database then we also need to create a migration then we need to increment the schema version and it will run the migration that would be in production so what do we have here hopefully it was uh a new income was added and now we can go ahead and render them on the allocations list but let's go ahead and do here uh G OD G commit minus M allocation table and create allocation and now let's go ahead and fetch them and render on the screen so inside our allocations where let's actually going to go ahead and in components create a new list a list of allocations you called allocations list. TSX the location list is going to be let's define it as a function allocations list equal not equal but a function return uh probably it's going to be a flat list where the data is going to come from our properties for now I can do here empty array render item I believe is going to be another component called allocation list item. TSX for list item I'm going to generate a basic default component like this allocation list item and in the list I will simply render a location uh location list item the component that we just defined now Advent let's simply export default for now uh location list like this and on the screen here in the allocations index we have have this link for adding a new allocation but below it I think we want to have the allocation list we no longer need this text we will need this link but maybe we're going to make it like look more beautiful like as a button I don't know we're going to see for now it's good like this um yeah yeah let's leave it like this just allows us to go to the new allocation page and now this allocation list is rendering so if I add here one two three we see free allocation list items perfect so far so good it's very it's just the barebone components now we need to create to fetch data about allocations and to subscribe to updates to observe at least similar to how we did in the accounts list we created the observable we used the accounts collections we query them and we enhanced our list by providing V with data so let's do it step by step slowly just to to practice more like these steps in order to help us understand this pattern because it's quite a different one like uh especially for me like the the whole process is new so it it it needs like to we need to to to practice this multiple time until we we learn it so we need them with observables from react using whiff observables we create this enhance function with observables the first uh properties is an array called trigger props like what properties should trigger these observables in our case is going to be no properties because when allocation list not this one but the the one that is going to be rendered not going to receive any data that means that here in the props we're not going to receive anything but we need to send something here such as allocations where from from allocation collection. query and behind the scenes it will also do observe which we it's optional so we can simplify it by like by doing this and lastly the thing that we export from this file should be wrapped around this enhance now this allocation list component is going to receive allocations so we can use them here instead of this array I believe we're going to have only one yes we do and we can take it here from item and send it to our allocation component like this item it has the type any but we can specify that no it's not any It's actually an alocation from our model allocation now on the allocation list item here we can also receive this allocation of type allocation and we can render here the in the text the allocation. date for example or create that and in text we can render the income create that of undefined because allocations not allocations allocation objects are not valid what is the object is it the created that or yes the created that is a object let's see what is the type of this console log and if I look in the console we need to check the type of that created ad let me delete it for a second okay so I think it's a date so what I can do is I can call created that dot to string because it's a date it doesn't see it as a date because I made a mistake not I didn't make a mistake but but in our model allocation I didn't specify the type of this created that which should be at date from JavaScript so now in the allocation list item I can call this to string because it knows that created that is a date so now it shows Friday April 19 at 1823 which is exactly correct so if I go to the new allocation page and do see five save come back it's automatically there because our list we are subscribing to new allocations to the deleted allocations so it displays here properly data what's going on here locations oh because I have to specify that it's a an array yes like that okay so that's our list now probably is going to be to a little bit adjust the the styles of this view so let's go ahead and import the style sheet and create the Styles container uh [Music] container income so let's do here style container sty do income maybe styles. dat as well and instead of two two string let's try a two to ISO string no to to to to to to local local date string yeah I think that's better with a custom Library like days. JS you can adjust like the format but for me I think that's good so I'll just adjust a bit the styles of this container I want to render them on the same line so Flex direction is going to be row justify content or maybe because this let's do here another view with a style do header and put the income and this one in the header because from this UI we have a special style for this header and let's do it like this so the flex direction is actually going to be on the header itself the background color I don't know uh Li gains borrow I don't know something like that let's go to the allocation list and see what's going on here if I had a style here background color red it's only like this but why because if we go in the application allocation index we have a container and the container has a lot of stuff so I'm going to delete all of them and leave only the flex one uh now if I go to back to our allocation list I can remove this one I can add here a Content container Style with gap property to add some spacing between the items maybe even more 10 and a ping 10 like this okay back to the allocation list item uh the header should also do justify content space between to move the income at the end the header will also have some ping like 10 the whole container will have border radius 10 and uh overflow hidden in order to hide everything that overflows hidden okay uh what else what else what else I think for now is good maybe the income font size 30 [Music] 204 font weight bold and some color green yeah that's good that's good let's add a dollar amount be for the income itself for a date I'm going to leave it like this no no biggie so yes uh one more step in the application allocations index for this link what should we do uh I'll do some kind of um I need some Styles so let's put put here a pressable which is a component that allows press events it's like a button to style this pressible let's do styles. button I will Define here the styles. button text string must be inside text what should we have a text inside pressible I don't remember that being the case but maybe okay so maybe we don't even need the text we can have text style here Styles dot come on styles styles dot do button oh I think I lost my style so I have to do contrl z a couple of times and only then so my button can have a background color I don't know Green Well very bad very bad but it's okay color white um margin 10 but the thing is that most probably we need as child on the link in order for the styles of this text to take effect and not render a separate one okay so let's go ahead and add the bit of pting as well align text align Center because we are working with a text font weight bold uh border radius five uh overflow hidden yeah that's good that's good enough so now if I press on new allocation we go here we can add here something save if I come back it's added here automatically nice so perfect most probably what I need to do here in the query is sort them the other way around or or should I invert the flat list no I think I need to sort it V way so let's see how we can sort Thing quering sord by so database do getquery sort by number okay sort by I don't know sort by okay q but where is it Q from where is it Q coming from okay it's from here so in our account list let's try to import this one the que and inside query if I do Q dot sort by and here I need to provide created at fail to prepare so let's see sort by and and yeah I need to also do Q ascending or descending allocations Q ascending I think this is the field so it should be created underscore at right yes so if I do ascending it's like this if I do descending it's our way around so I need descending most recent allocations at the top so if I go here and do one save and come back the one is here at the top and I can do that actually like go back automatically on the new page here under a save I can do here router imported from export router somewhere dot back so if I go to a new location and do two save come back it's here free save come back it's here perfect perfect maybe I can also reset the income here to empty string uh four save come back it's here perfect so with this we have our git status and you see how fast everything is working get add get commit um Fetch and render allocations okay so what's left is the account allocation account allocation oh boy not sure if we actually managed to to finish it today um so I'm thinking maybe we should do part two what do you say hello goodbye from Barcelona hello slow how are you doing 4 minutes left and hell and the food up tutorial took like three weeks to watch all the eight hours amazing but yeah hopefully you found that valuable Hello from ukar Hello Siri okay so will I manage will I manage to implement this I don't really want to rush it too much so because we have like 20 more minutes and this account allocation is when doing the allocation like when adding it we want to see different accounts bare percentage and automatically calculating the the value based on it so let's try to first in the allocation new here we actually need we need some data we need data about accounts so we are going to have also the import with observables with observables um and we are going to create here const inhance with observables it's not going to receive anything but we need a list of um a list of accounts because when creating a new account we need to c a new allocation we need to know the accounts that we want to distribute to so accounts equal accounts collection do query uh account now instead of exporting this function I'm going to export the fault enhance that function how is it called new allocation screen so what's going on here unused label oh because uh I need not to I need to wrap my object with round brackets in order to make sure that we are returning an object it's not a body of a function now we're going to receive all of these accounts here accounts uh account and Below everything I'm going to be able to go ahead and do view maybe for all accounts I'm going to map through them like simply accounts. map let's define the type of this account array so I'm going to map through each account and I'm going to render a view where I will simply render a text initially with account. name and B account do cup which is current allocation percentage we need to know the percentage that we need for that account when mapping we also need a key so we can use account. ID as the key and let's go to the new allocation so we see that we have a new a only one profit account if I'm going to add here for example taxes that is 20% and then expenses 60 I don't know 60 Add accounts and then come back to to this it automatically adds here so we see the percentages that we need to allocate to those accounts now it's time to calculate the value based on the income multiply by this percentage so the value is going to be our income or better say number. pars float income multiply by the account percentage and divide it by 100 so it doesn't really work because now it's not nothing there so I think we can initial it with zero maybe or we can say number float yeah it's okay and if I do here 100 we see that for profit we receive $2 taxes $20 and expenses $60 so that's the whole goal of this application simple calculator so I think I will use the same input Row for our view here what will it do it will make it a row and for for the first this one I'm going to do Flex one so now if I do 10 we see, we see automatically updating and calculating there perfect and the next step is going to be when we save we want to save these values inside a new table called account allocations account allocations let's see if we have time because I believe we [Music] might or not to rush it and to do it properly next time yeah it's going to save it's going to show it here but I also want to display later like how was the distribution there so yeah probably we're going to have to do part two of this tutorial because as I said most probably uh I'm going to actually publish this application because at least I'm going to use it and maybe there are other people who are running their businesses and following this profit first approach uh the thing is that this profit first approach can also be applied to personal life as well like if you have multiple goals and you define like the percentages of your income that goes there you can apply it and uh is going to help you so yeah uh let me go ahead and check what changes we have done get status G add G commit [Music] calculate account distribution okay so that's this and should we work maybe on some UI or if you have any questions guys feel free to to ask that was intense that was really intense but I'm really happy how it turned out uh because as I said before like in November I tried watermelon DB I had some issues with a setup with a configuration but now it looks that it's working uh perfectly fine so yep love it let's see if on Android is going to work as well so let's go first of all into the account let's go to come on Android what's going on you're laggy yeah have Android is not cooperating let's try to open it again let's go to accounts let's create an account for example uh profit 10 20 add account then tax 20 add account okay now if I go to allocations and try to add a new allocation 123 it's going to calculate automatically based on the profit 25 perfect if I save it's going to save it here and display it in our allocations uh you might think that we can simply calculate here based on the cap but it's not it's possible like instead of having this stuff instead of having this stuff that will display below like here the distribution we can calculate it based on the the current cap uh and based on the this income the same way as we calculate on the on the new page like here but the problem is that the cap is always going to change like your every cord you're going to change it to move more towards the target allocation percentage so if you change it and later view it it's not going to reflect what actually happened back then so that's why uh we're going to have to store in the database the actual amount that you that you allocated there and the cap the the cap that was at that specific time not at the moment but at that specific time so yeah that's going to help us make sure that even when we update data for example we go to accounts we're going to click update we're going to change this percentages it's not going to change how we view it here so that's what we're going to do in the second episode of this application and works on Android on iOS everything works fine for so yeah I'm reading now about this writers and this is is the actually recommended way of doing it instead of defining inline writers it would be better to take it from the inline stuff put it on our model as a separate function and then call this function so an example of this would be uh let's say creating the allocation new allocation screen so that would mean that on the model allocation we can have a writer which is a decorated imported from here and I think because we are creating we're not updating we changing something it should be static and it should also be a syn uh it should be or maybe it should be a Constructor Advanced readers delete writer create a new record create uh create let's try with simply create and we are going to receive a income as number so what's going to happen here is going to be exactly what's happening here inside the writer method so the benefit is that by defining this writer it's not a location but it's uh that's a bit I'm not exactly sure like if I'm doing it right income I don't need to parse it as float it's already float so it's equal to to income so let's try to call it as allocation do create instead of all of this so allocation dot create and there is going to be a number parse float so let's try new allocation one save possible and handle because canot read property right of undefined right of undefined oh because I think in the create we need to do return a wait new collection 212 three save possible unhandled inline writers writer method I think add comment but this is under a post adding a comment there uh V do collections to access database collections V do collections h no batch update super yeah like I I don't like that it doesn't explain how to Simply create an item like yes I understand like how to to update how to delete and stuff but how to create something and it shows how to create a comment inside a post yeah okay I understand but how to create not part of a post object but as a part of a class like as a static method it's not explained which is a bit weird writer static a think maybe like this cannot read right of undefined yeah weird a bit uh new comment await V collections these collections. getet comments. create cannot read property right of UND defined yeah weird but I'm going to check uh more and see how we can do this uh like this now I'm going to comment it out and we're going to have oh because here wait a second a location is a location I find no no no no so I'm going to leave it like this so it still works perfect all right guys so that was it for uh this tutorial I hope you enjoyed it we're going to have a part two where we're going to improve it with more relationships with more data and uh hopefully I'm going to have this application published so if you're interested uh it's going to be somewhere there if I'm going to still have time but yeah I intend to have a second part tutorial so keep an eye on the channel subscribe for more updates and uh yeah if you enjoyed it make sure to to like the video comment down below whatever tutorials you'd like to see in future and I'm going to
Info
Channel: notJust․dev
Views: 17,489
Rating: undefined out of 5
Keywords: vadim savin, not just development, notjust.dev, live coding, react tutorial, react native tutorial, react native for beginners, React Native, step-by-step tutorial, Offline-First Apps, expo, watermelonDB, build finance app, local database management, local-first application, data syncing, efficient data handling, expense tracking app, debugging react native, finance management application, build a local app in react native, expo local application, sync data watermelonDB
Id: x7KE4JD-Q9A
Channel Id: undefined
Length: 238min 46sec (14326 seconds)
Published: Sat Apr 20 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.