YTread Logo
YTread Logo

Building the Ultimate Workout Tracker with React Native & MongoDB

Mar 04, 2024
What's happening? Nojz developers, welcome back to our traditional Friday live stream. I really missed life during the Christmas season, but today we're back with a fire tutorial. Today we are going to create a fitness

tracker

and in doing so, I am going to learn a lot of interesting technologies, there are many fitness

tracker

s and in fact I co-founded one of them. You can search for it on the Market if you are interested, but in this tutorial we are going to focus on a couple of main and important features that a fitness tracker should have. First of all, we will focus on creating the exercises database in which we will be able to search, filter, see the details of different exercises and then we will create. the logging experience to record your exercise sets while you are working out in the gym, finally we are going to develop the progress and show it in graphs and do all this. with the following stack uh Tex in the front end of course we will use

react

native

with Expo with Expo SDK 50 and for navigation we will use Expo router this will be a great tutorial to improve. these technologies and on the backend this will be a complete tutorial.
building the ultimate workout tracker with react native mongodb
We are going to build both the application and the backend, so for the backend we are going to build a Graphql API using IBM Stabs and ourselves. We will connect it with multiple data sources, on one hand we will connect it with a public API, not public, but it will provide us with exercise data and we will connect it with a custom mongod DB database that we are going to create, we are going to learn how to host it with

mongodb

Atlas and that will serve as a database where we will store information about the different sets that the user is doing, so all of this together will be connected. with Graphql and we're going to use IBM Stepen to do that and in fact Stepen is sponsoring this video so a big thank you to IBM Stepen for making this project possible.
building the ultimate workout tracker with react native mongodb

More Interesting Facts About,

building the ultimate workout tracker with react native mongodb...

If you're not already familiar with Stepen, this is a unique form. and a very easy way to create scalable Graphql APIs in the cloud by simply declaring a couple of lines of code and letting the steps do all the heavy lifting for you; in fact, you will see in detail how everything works during this tutorial. So if you are ready, let's get started. I am very excited. Let me know in the comments where you're viewing this from and let's start with the introduction, as always. I prepare the resource pack for you. You can download it in assets. noz.de trainings and where you will find this presentation that will help you move forward and also some dummy data and the source code of a final application when we finish this entire tutorial will be divided into three parts, everything is This will be finished today in this video at the end, and in the first part we will focus on the UI, in the second part we will focus on the Graphql API and lastly we will focus on the functionalities for the fitness tracker features let me see the live feedback and if you are ready I think we can start.
building the ultimate workout tracker with react native mongodb
Hello everyone. F Al says he watched all 24 demember videos, that's exciting, yeah we did a lot of tutorials. in December, anyway, let's get started and I'll come back to the live chat throughout that tutorial, but we're limited by time and I really want to get a lot done today, so let's go ahead and get started. When initializing a new project using Expo to do that, we will open a terminal window and use the Expo creation tool to initialize and boot a new Expo project. Let me delete everything, let me go to a. folder where I keep all my projects, somewhere, yeah, I think it's here, give me just a second to change this to yes, so now when you navigate, when you've navigated to a folder where you keep your projects, let's go ahead and initialize . our Expo project for that we will use npx, you don't need to have anything installed on your system other than nodejs and npm and we will use npx which comes with nodejs npm and other tools and We are going to use that to create Expo.
building the ultimate workout tracker with react native mongodb
This is a small tool for initializing Expo applications. We will specify at the latest to take the latest version of this tool and then we will provide the name of our project. of the project will be trainings and DHT to choose a template and I would like to start with a blank template to help you and show you step by step everything you have to do including setting up an expert router because if we start with a template and if you don't know everything, um, all the things about exper rou, it's going to be a little confusing having a starter project with a lot of files, so starting blank and doing everything ourselves will be the best approach and I hope everyone understands how to do it and follows and implements while we hope our project initializes uh let me see the live chat uh Vol VY hello from Russ hello hello from Sri Lanka hello mishan let me zoom In at a time like this, I'm still playing around with what the teleprompter is called so I'm reading the comments of the teleprompter.
Tanzania, East Africa, hello, gu island, where is it so long? We don't see each other, yes, we, there were like three. weeks or something, I really missed being live, and yes, we actually planned a lot of live streams for this month, we'll probably do them twice a week because we have a lot of ideas, you sent a lot of project ideas too. during November so I really want to see a lot of them so after we see this message your project is ready let's go ahead and open it. I can do LS to see that it actually generated this training folder in this directory, go ahead. and open it with the editor of your choice.
My preferred editor is Visual Studio code, of course, and I'll open it using a shortcut code and the name of the folder I want to open if I check here, here's the um. project that was generated before jumping to this structure and files. I would like to go ahead and I would like to go ahead and start this project to see it running on a device and after that we can talk about the project. structure so let's go ahead and open up a terminal here within the Visual Studio code and let's go ahead and run npm start npm start will actually run Expo start which will start the Metro package uh and this will be where our application will connect and grab the package from the JavaScript code to run the application we see here a QR code and this will be the easiest way to run the application if you do not have the environment configured with xcode and Android Studio.
What you need to do is continue on Playm Market or App Store on your physical device and download the Expo go app. After you have done so, simply scan this QR code with your physical device and you are ready to start viewing the app. running in my case I'm going to run it in the iOS simulator because I have the the android emulator, we press a and for these two options, actually we need an environment set up to run an iOS simulator, we need xcode and xcode comes with the iOS simulators to run it on Android, we need Android Studio and Android Studio avd emulators where is my emulator here?
Is this the application that is running? Yes, if I press if I double press R, this will reload the application and we will see that it is actually bundling and taking the code from here at any time. Over time, if you make a mistake on something here in this editor and you don't see the menu, just click C and this will clear the terminal and show you the menu from where you can interact with your Expo server, now what we see in the The screen opens upjs and we start working on your application, let's do it if we open app.js, this right now is the entry point in our application, uh, and if instead of this text that we see here, I'm going to say Hello world , save a file, it is automatically updated and updated on the mobile phone without any manual update, etc.
I'll also make sure to set it up, maybe set it up a little bit later, but no. Let me do it now, this is an optional step, as you can see, everything is working fine, but my V code doesn't like what I'm using here GSX and I'll push this JavaScript at the bottom or maybe this thing. and then configure GS config, this is adding a new file in my folder called GS config with some default configuration and what I will have to change is this GSX. I will

react

GSX and now, if I look up. GS everything is fine here again, this was optional if you don't have any red warning you don't have to do that, in my case I had to do it right so here are our upjs and here is our first page. that we see on the screen what we are going to need is that we are going to need some dami data from a list of exercises because the home screen will probably be a list of exercises if we open an exercise that we are We will see the detailed page of that exercise if we look in this UI, the first step is done, we set up a project with Expo, let's import the dummy data and the dummy data that you will find by downloading the asset package, the link. it's in the description below, it's also pinned somewhere there and you can find it under assets.
Training N.D after downloading this you should receive the resources of this training with a presentation and data folder. Let's go ahead and drag this data into the assets directory, so if I open the assets now I have the data there and in the data that we have. a Json file with a list of exercises, this is an array and each exercise is an object that has a name, has a type of muscle equipment, difficulty instructions, etc., let's move backwards in our application. GS and let's import the Dam data from our exercises later we will query this data from our API, but I don't want to get too complicated from the beginning, that's why I am providing you this Dam data so that we can First, focus on the UI, let's move on and let's import these exercises from where we are in app.js, so we need to go to the asss directory first, but the assets are in the current directory, so put a dot when the assets after that we enter the data. asset data and we take the exercises, we make the Json file now if I go ahead and for example, inside our application inside our location, if I go ahead and do console log exercises, where will we see this console log?
This console log we will see if we look inside the terminal that is running our application, that is where all the debugging errors will appear, that is where all the console logs will appear, so we can see if we see this amount of data, they are a lot of data, then everything is fine and we import it. actually correctly our exercise data and here's a good way to explain, if we want to go back to the menu, just press view on your keyboard and you'll go back to your app from here, you'll see that By pressing R inside here, you're going to reload the app and for some reason it didn't want to reload from the terminal, but if I press R twice when focused on the emulator, it will do it anyway.
Here we have a list. of exercises let's go ahead and just the console records the first, the zero position of the exercises, if we verify that it should be an object with properties, difficulty, equipment, instruction, class and name, okay, let's go ahead and take this and save it to a separate sep variable called exercise and let's take the exercise at position zero for example, now we are going to work with this exercise to try to display information about it on the screen, for example, at the moment we see that we are using an element of text.
The text component imported from react

native

is rendering hello world of work, but what if we want to render the exercise name? We may be expected to do the exercise. name but that will literally say exercise. name on the screen, so how do we access JavaScript variables within our GSX syntax? We do this by placing it in cly brackets. This is sometimes called a portal and it gives us access to JavaScript variables and JavaScript syntax for expressions by just doing that, we see that the text turned into tilted hammer flexes, that's good, that's perfect, uh, and we can, for For example, represent another text below with the exercise point, what else do we have there?
Maybe muscle and we see that this is a biceps exercise, maybe besides muscle we can render some other text, for example you can say muscle is this and then we can add something like equipment, equipment will be exercise, do equipment, so that's how we see both the muscle and the team on the second line here, perfect. but how do we give style to these texts? To style the text, we can provide a style property and a style property is something that most components have. Here we are starting with Cly brackets to open the portal to JavaScript and inside these Cly brackets inside this portal.
Let's add another brackets to the object that represents the styles of our native rack text component. We're styling everything with simple objects and the objects and yes, let's say The Styling property names are inspired by CSS, but they're a little bit different, so of courseFor example, if we want to increase the font size, we will use a font size property and we can do here 20, since we can see that the font size of this has already increased, you can increase it even more. 24 I'll leave it at 20 but increase the font weight a little. The font weight can have a value like bold and it will actually be bold or it can have a value of uh, I don't know, let's say 100 to 900 where 700 is bold, uh, 400 is normal and let's say 500 is a little bit more bolder than normal, so I think I'm going to use this 500 for the second one I'm going to give it a style and I just want to decrease the color to decrease the importance of this message and by decreasing the color to let's say soft gray or just gray I don't know what it is but it looks light gray, it looks good for the muscle

building

exercise, what I can do is what I can do.
I'll leave it at that, so that's how we're showing it and we're learning how to style our texts. So far, we are designing everything with online styles. Okay, and in some cases I do that too, but as a best practice, we're trying to extract and separate the rendering logic that is our jsx from the styling logic that's here to do that, we're using a style sheet. that is also imported from react native uh where we store different objects for our styles that we have here, for example, this style for the exercise name, we can define it in the Styles sheet with a property name that we want, for example, name of the exercise and here Let's put all the style parameters we want, let's copy them from here and put them inside our style sheet.
Now let's change from an inline style to a style that we defined using the style sheet to do it, as you can see our inline style. is this object which is the yellow braces, let's go ahead and delete that and we're left with just a couple of braces for our JavaScript portal and here we can access the styles, make the name of the exercise like this, we have the same styles, but now we don't they're inline, they're separated from there, we can do that too with the exercise subtitle uh and for the exercise subtitle, I'm going to move a color that we specified there, I'm going to move it here and we'll delete it. object and access styles. exercise subtitle, okay, okay, but right now, if we consider this view to be a simple container similar to a div in web development, the initial view here is if we consider it the view that represents the entire page. that means our exercise doesn't have its own container, so we can't style it independently, for example if I just want to add a background color to the exercise or some shadow or something like that if I'm going to add it to the container. like here red like the whole page is going to change.
I want to add maybe some styles on the row that represents an exercise so let's add some spaces here and wrap our text inside a view. This is a container and now this view. represents an exercise, let's go ahead and give it a style. Styles are not the name of the exercise, but they contain. So far we haven't defined these styles yet, but let's copy and define the exercise container here, for example, if we want to change maybe the background color. I think a good way will be if the background color of the exercise row will be white, but the page will be something like gray, maybe a profit loan, this is a very light version of a gray. uh or maybe like Snow White, but I think B games are cool now.
The thing is, yes, we have the exercise container with white, but why is it so tight? One reason is that the container that represents the page has this Content Center justified. If I'm going to delete that, we're going to go to the Justified Content Center, let's leave that, but let's try to delete a line item center that makes the exercise container centered there. If I delete it now, the line takes up all the screen we need. Probably some padding in this container, so let's add padding 10 to make sure the line doesn't go all the way to the edges of the screen and inside the exercise container, we can also add some pt to have some space inside. this line will look better if we round the corners using the edge radius, so um, yeah, I think it's good, fine edge radius, okay, yeah, I think it's good.
I'm going to simplify a little. I'm going to remove a muscle. Actually I'm just going to leave one muscle because it's clear that if it's biceps it means it's biceps and I'm going to do the same thing with the equipment uh and to make it look better maybe we can make it a rope. So two, not in capital letters, but what is it called? Let's look it up on Google. JavaScript uppercase text, first letter. Are there capital letters? Make capital letters. It will work? Undefine is not a function if I do here ABC uncapitalized to local local to go down to string to uppercase oh boy, let's make everything uppercase.
I'm not sure how good it will look, but that should be exercising the dot muscle and the same for the uppercase team, okay, now I'd like to add a little space too. between these two lines there are different ways to achieve it, either you can add a bottom margin on the name like this bottom margin five. I think it would work, add the space or if you don't want there to be a space property. and if you add it in the container, if we add Gap here five, it will add this space between all the children, so I think this is a more elegant way, okay, okay, that's what looks good, looks good , maybe, let me see, yeah.
I'll stop here for one line style and then we can see if we need anything else. Let me check the likes and comments. I think I'll also make a compromise so you have a good story. of all the changes we've made, let's do git status, get OD, commit an exercise or let's do an exercise, well, turn on the standard tutorial, that would be nice, I'd really love to check it out, why not tamagi? I love Tamagi. I think we also need to do a separate tutorial. I actually have a startup I'm

building

using Tamagi and it's nice how to play videos in the background with player control and notification in Expo.
For that you would have to do it. I'll probably, um, create a native module or maybe there are some solutions available. I haven't checked it yet. JavaScript does not have an uppercase string method. Unfortunately, oh yeah, um, for some reason, I remembered seeing something, maybe it's not available on uh. ER Miss, maybe it's because I remember something like that where I was wearing some um under Dash or how I was visiting her home country. It was nice. I also managed to get a lot of work done but spend some time with my family and I also managed to get sick twice so that wasn't fun it was quite cold there and we managed to get the flu and ah how unpleasant okay so let's continue now we have one, um, we have and we can do an exercise, for example.
I'm going to change the index here to one, we'll see that it changes the name and things like that, but how do we render a list of exercises to do that? We have a separate component called flatlist in native rack and I'm going to render the flatlist here inside our page, so let's render the flatlist. The flat list will be a self-closing tag compared to a view that we open and close here. A flat list, uh, has no children. It has nothing inside, the flat list is managed through properties and there are many properties in the flat list that we can manage, but there are two required, the required properties are data that must be an array, the data array we have. we want to represent as a list, our array is these exercises because if we look at V Json V Json is an array of elements, the second property is called rendering element and this should be a function that specifies that tells the flat list how it should represent each one of them. element in this array, so that function, similar to a loop, will be called multiple times for each element we provide and what we return from that function should be a GSX that represents which UI we need to render in the UI. for each element there, because it's a function, let's start by defining this render function, sometimes if I spit it out like it's a little confusing, so let's go step by step, like I said, the render function is a render element , wait for a function that returns something from GSX, so let's do this function, maybe you can do it like this, even so, this is a correct function and it should return something from GSX, what GSX should return, what should it render on the screen, well , it should render this exercise container because, as I said render element will be called for each exercise in that array, so for each exercise we need to render an exercise container like this, now we see many exercises in this list, let's fix the styles, etc. but now let's focus a little on this rendering element, the problem is that now they all show the same data, that is because within this component we are using the exercise which is always the same, but how do we know which element we want? are currently being rendered because the render element will call this function for each exercise in the array, let's know that because the flat list will give us the element will give us many options in this function, so there will be let's say props, a of the properties will be called element, element that we are representing, so here if I change the exercise. name a props make element let's see that all the names are different and they are exactly like the first one is tilt Hammer cool curls we see it here grip white and so on, so the properties are an object that has an element in vyor, let's continue Let's go ahead and simplify this by destructuring the element immediately from props, so instead of props I'm going to add query brackets to destructure a property of that object and the name of that property is element, now we can simplify this to item. name and we can use element to do something for the other instances where we call the exercise this way now all the data comes from the element data besides the element there is also an index and the index can be like I don't know let's say index Dot and the name, so we'll see one 0 1 2 3 4 up to nine uh.
I'm not sure if we need the index. I just wanted to show you that they have an index of the element that we're rendering and because this is an arrow function, this can be simplified because we're not doing anything here, we're just returning, so I can eliminate a return statement. I can remove a bracket from here, the opening bracket and the closing bracket, from here make sure to correctly remove the ones that match. and I will delete semi columns from here and then I will press save and this will become a simple statement because in the Arrow function, if we do not provide the curly braces, the expression will be automatically returned from there, so now it becomes much easier now we don't need the exercise here because we are not rendering one of them, we are rendering a list, I mean all of them, and the next step to further simplify this flat list is the rendering element H, this is also true for loops, usually , when we have a loop, the logic we have inside the loop needs to be extracted into a separate function that handles the execution or the logic of an element, then it can take the logic of an element. in a loop to handle it for all elements, that's the same here, a flat list with a rendering element is a loop, so the logic of rendering an element should be extracted into a separate component and then the flat list will be a lot more clean. that we need to create a custom component The custom component in react is a simple function so let's start with you can declare it with the function where with the arrow function it doesn't matter it's personal preferences here because we have a function app.
I'm going to go with the function, but I really like to change it completely from the arrow function to the name function, etc., let's give this component a name. It should start with a capital letter and that's how it should be. We are defining a component for an exercise. List of exercises. element, this will be a function and it will return something from GSX to render on the screen what it will return. Well, exactly this we see with style with element, etc., come on, why don't I want to appear? it should be like this, well, where do we take the element from?
The element will be a property of our custom component. A property comes from here via props and we can go ahead and destructure it the right way instead of taking props from the element. We're going to destructure the props element like this, so now we're going to have access to the element, let's go ahead and render the exercise list element in the render element here like this, let me render a custom component, it's similar to how we represent anything else we've used so far, like a view or a flat list, we're using these square brackets, uh, we say we provide the name of our component exercise list element exercise list element and like not we have no child inside it, let's have it as a self-closing tag, but we shouldprovide a property element that we expect here and the value of this property will come from the rendering element here and so, our flat list now becomes super easy to understand.
When we look, we see that it has data that is a series of exercises and it has a render element that simply represents an element of the exercise list. The next step will be to extract this custom component into its own file, rule f. is to have one component per file with some exceptions, but yes, this helps us keep everything clean. Where are we going to create the file for this exercise list item? It doesn't really matter, but I like to keep all the source code of our application. Inside a folder called s SRC and V, we will create another folder called components, this is where we will store our reusable components.
Let's start with the exercise list item. GS or better GSX specify that this component also has GSX syntax, GSX is this syntax that you see here to represent the components of the UI elements, now let's go ahead and take the function exercise list element. I'll cut it from here from our app.js and move it to the exercise list item. Here we see that we also have to import the view, the text, etc., and when this happens, I usually like to go back and take all the imports from the previous file, move them to my new file and vs code tells me what, which ones I don't need and highlights them with a gray color, for example, exercises.
I don't need it here. Flat list. I don't need it here. Styles. I'll need it in a moment. And status bar. I don't need it here. The same with styles. I will do that. Come up again. GS I will copy the entire style sheet from here and move it to the exercise list items component and make sure to remove the styles that I don't use here, for example the container is something related to the application, not something related to the Exercise list item now, the last thing we need to do here is go ahead and export this default function so we can import it into our files, let's go back to our application.
GS and let's import the exercise list item from the source components. Now everything is working, we see it here, but let's finish everything by cleaning up our app.js styles because here we only need styles for our container so we can remove the ex.

workout

styles and what else, what else, we think our list is below the notch. This can be solved with a safe area view. I don't want to get into that because it will be automatically sold when we enter navigation. so just adding the margin top 70 here will solve this problem and even add maybe not the margin top but padding to have the same color.
Yes, make a top st this way. Now how do we add space between these elements that we have here? Well, one. One way would be to add some margin to the exercise container, but as I said, usually the spacing between elements is best managed using a space property. We have a space property where if we add the Space property on the container, nothing will change because the container even if it looks like it is the parent of our exercise list item, in fact the parent of our list item of exercises is a component inside the flat list, so the flat list represents a component and then it is rendered inside all the exercises, what we can do is I can provide a style property here and we can provide this Gap here Gap 10 again nothing changes much because the style is for a flat list container but there is another container called content container style and if I add Veer only now it will work. five will probably be better perfect like this, we have our flat list, we can scroll through it if we're going to have more exercises, for example, if I'm going to double the number of exercises that we have here.
I'm going to see that we can easily scroll through them to the perfect ending. I'm going to look at it again here and the last thing I want to show you about is a flat list of where it is in our r. GS, we have a flat list whenever we represent lists of elements, whether with a flat list or just mapping an array and rendering them, they must have a specific key property to be able to return to um um cache vam correctly and render only specific elements in a flat list, this key can be automatically handled by us and this happens when our data has an ID or a key property because our data does not have an ID or a key property, what we can do is we can. telling the flat list how to extract the key from our data key extractor is a function that will receive the element and from the element we have to specify what is a unique key for that element and we can take the element. name in this case and will use the element name as the key, it will work perfect in many cases, it may not work well if you have duplicate names, for example if incline hammer curls will be for both, we will see this error when finding two children with the same key, so make sure your key is something unique that identifies the item and if you have an id or a key, you won't even have to worry about the key extractor. it will be automatically taken perfect so now we assume that the names will be unique so we leave this key Name of the constructor you can also take the second parameter I think it is the index and you can have a combination of name plus index and in that case even if the name is unique, it will have an index at the end that will make the whole join unique, but yeah, I'm not sure if I need it, but we can leave it like this and if I reload the app, let's make sure we don't have any errors, no, no, I'm going to go ahead and do git add git commit uh perfect

workout

list, how are you guys?
Are you following me online from Kenya? Hi Brian, In the style sheet, you can provide the TX transformation. capitalize, that's perfect to be honest and yes, it will work, so this is a little trick on Styles, that's where I was. I was taking it in the exercise list item, um, if I go to H, but in that case I'm going to need to let's say delete them from here and I'm also going to have to put them inside their own texts to capitalize them independently this one and the second one and I'll provide here a style styles mod I don't need exercise here I need U no I don't know a subvalue something like that and I'll give it to the second text as well and if I go to the subvalue here I can do the text decoration, the transformation of the right text and there's the capitalization and we can capitalize it not from the JavaScript, but from the Styles styles and yes, it actually works fine, perfect, add caps.
Thank you very much for mentioning that we need typescript in Expo, we need typescript, it is very easy to add typescript, just rename abjs to ab. TS and run the project again and Expo will automatically detect it and configure your project with typescript, so yes, you can do it. I'm not sure if I want to do it right now, maybe I'll keep it simple with JavaScript to be honest, but if we look at our plan of attack for the UI, use the prey data, come up with a list of exercises, the next step will be use expert router to set up navigation so we can create the exercise details page that sounds like a plan and we can start with that, first of all, export router, what about export router?
Well, as long as our applications have multiple pages, it is rare that we have single page applications, for that we need a navigation library, the de facto navigation library until now. for the native app it was straight navigation, it provided different types of navigators, like tabs, drawers, templates, etc., but the thinking about R navigation is that we had to, yes, we had to create the screens, that's obvious , but we also had to configure them separately. these screens, for example, in let's say this TXS and we had to build the navigation tree ourselves. I wanted to show you an example.
I can't find anything interesting, but now you can imagine. I think a year ago um aan bacon worked and released the exper router exper Router is the first file based navigation system for react native applications. How does it work? As a developer, we simply create files and folders in a specific structure and it automatically assigns them to the screens of our application so we can wish. You can focus only on creating screens and not think much about setting them up in the navigation tree etc. It comes with additional benefits like deep linking, um and then yeah, initially it's a learning curve, it's something new, it's something different, especially if he's done it.
It didn't work with other file-based navigation systems, but once you get used to it, it's very easy to add new screens to restructure your navigation. However, if you have experience with nextjs for example, which also uses a file-based navigation system, it makes sense to you a lot easier, so that's what we're going to use today, let's go ahead and find the documentation for exper router and, um, another note is that explore router is built on top of R navigation, it's no different, it just helps us configure. r navig just configures r navigation for us and a lot of configuration for different screens, where RE navigation comes from and sometimes we have to go for example to see how to configure a Tab Browser or how to change the icon or something like that, but let's continue with the Expo documentation for the Expo router and immediately go to the installation, the quick start shows us how we can start with tabs, but I want to show you how we can start from blank space. and let's set up the navigation ourselves, so scroll down until we see the manual installation on XO SDK SDK 50 which was released a couple of days ago at the time of recording this live stream, if you watch it later it will probably be longer, so Expo dk50 works with the free version of Expo router so let's go ahead and the first step is to create an exposure project which we already have check the second step is to install the dependencies so for SDK 50 and above let's copy this list of dependencies. our project, let's open the terminal, clean up the terminal and paste the command, it will go ahead and install the exper router and a couple of other dependencies that Expo routers need, like the native R display, like Expo binding the constant status bar, etc. ., let's wait until that happens, why not use export outter V free?
Actually, we are using export outter V fre. If we look at the package.json right now, after installing it, we will see that we have expert router version 3.4.3, maybe it is different. for you, but you should at least start with perfect threes. Let's go back to the documentation and we need to configure the entry point right now. Our entry point, as I said, is this application. GS and if we look at where in the package.json we will see that yes, like the main entry point, it is something that comes from the Expo entry on the Expo router, we need to change this so that this is done only once and then we can forget about that, so let's copy this main line and in package.json change it here, make sure to add the comma at the end and now the entry point is the Expo router.
We need to modify the project configuration to add the schema, this is used for deep linking uh and in the application. Json in this setup, I like to add it after the slug, we need to add the schema, the schema will be used for deep linking and for example, yes, let's call it training, we can also install a couple of additional dependencies and exit. Out of the box, our application will also work on the web, yes, let's do it to follow everything step by step, even though we don't need them right now, let's install rack native web and R Dom these two Li these two.
The libraries will allow our application to run on the web and is also the only thing we need to change. Json means webpack should be Metro, let's go to ab. Json, scroll down until we see web and add the package here. We want Metro to package the code for the web. The next step is to modify B.C config.js and what we need to do is add these presets for the Babel Preset Expo. let's see, let's open Babel config.js, we have presets and actually Babel preset Expo is already here and if you are updating, okay, that was it, now we will have to restart our server and also clear the cache, let's go ahead and continue. to where our application is running and let's stop the server, let's start it but let's provide Dash d-- sure, if you're using npm start, you need these two, a set of two scripts, if you're running npx Expo start, you don't need them.
I don't need two of them now, run it on iOS. I'll close the old one and run it again and what we should see is the Expo router home page. Welcome to the Expo. Do not press this button yet. This is the home page when we have exper outter installed but we don't have any screen yet. I said exper router is aFile-based navigation system. The way it works is that it looks in a specific folder called and from the top directory all there is are the screens. which Expo represents right now, we don't have an active directory, you can create it in the root directory or also in the source code, so let's go ahead in Source Code, create our application directory and this is the Expo router folder again, everything what's here should be about screens and layout, nothing more, nothing less, and the first screen we're going to define will be a home screen.
A splash screen is usually called index.js inside this splash screen, let's go ahead and move everything we have. currently in the app. Gs, because that's our home screen, let's move it to index.js, save it, and we actually don't need dogs anymore, so after confirming that you copied and pasted correctly, you can go ahead and delete the app. GS here because it is no longer necessary now all the screens are inside the top directory. Let's go ahead and probably restart it again where I'll reload it to see if you see the new screen I added if not.
It's not seen, it's just, yeah, it's not seen, so oh no, it's actually seen. The problem is that now that we moved the code, the relative path is different, so the assets are no longer in the current directory, but are a couple of directories up like this. I think so and the same for the exercise list item a couple of directories up and let's reload. Yes, here we have our application, using the Expo router and as I said, the problem with the above will be solved when we include navigation. so in the container we no longer need this pting top 70.
I'm going to remove it so that it now looks like this. Maybe the game board is too dark. What is a lighter version of the straight gray native colors? I can take them as adequate. color but I'm lazy and I'm going to use something from here uh very very very light gray ghost white I think it's ghost white yes yes ghost white uh it should be Quest White H maybe I should remove it from here, let it be a wide background and in the ex size background here let's use white cost. I don't like it, yes.
I'm going to have it like this, maybe adding a background for our H element, not a background but a shadow for our elements, will make them look better by adding a shadow. I usually go to a shadow generator that reacts to the native shadow generator and the first one. one here is a tool that simplifies the way you create the shadows I'm going to decrease it to a value of two and I'm going to copy these very different tiles I'm going to go to the exercise and I'm going to put them in the exercise container here and also add the comment Shadow and yeah, it looks a little better now.
I think so, I don't like that it doesn't have the shadow on the left and the right is like an H, maybe a horizontal margin. two or three like a very small one just so we can see the shadow there, yeah, it's better now, okay, perfect, uh, perfect, perfect, perfect, it looks good, we have our R navigation set up, but why did we do that? We did that to have a separate page for the details of our exercise before we move on to the next step, let me go ahead and confirm everything configure the Expo router configure the expert router, so again, why did we do that so we can click? in one of these elements and open the details page where we will show more information about the exercise and maybe later one like a graph, etc., it will be a separate page, a page or a screen in external export to create. we just create a file inside the application folder of our application so let's create a file called exercise size exercise size do GS here let's do what um let's export come on my keyboard export default function exercise size screen of details this is going to return.
Start with a view that will render the container of our page uh and the view is imported from React Native and let's just render the text here. Exercise details. The text should also be imported from React Native at this time. How can we not? navigate there, uh, if we run this application on the web here by pressing W here inside where you'll see, press W to open on the web, if we do that, we see the list of items and on the web navigating to a page is much easier . because we can simply change the URL at the top, so at the top, if I simply add to the Local Host forward slash exercise, we see the details of the exercise, which means that the Expo router automatically creates the screen for us .
Now I just wanted to show you that by simply creating this file and exporting a component, this component becomes the screen that is rendered when we navigate there and the path of that screen represents the URL or name of a file, including the different folders in which that is located, for example, if it is going to be inside another folder, we are going to have to make several bars, for example, details of the exercise bar. Now we actually want to navigate when we click on one of these elements. To do this, there is a component called link.
Let's open the exercise list item. and let's import a link component from the export router link from the export router a link is similar to a text component, so I'll start maybe you can look at it for a minute and see what I'm doing because I'll end up with a different solution, but now I just want to move towards it, so a link, as I said, is similar to a text component and I can simply replace this text representing the name of the exercise with a link here, however a link needs a similar h to how we. we have on the web the links on the web and the hre is going to be a forward slash exercise because that is the name of the screen and that is the path of that screen exercise like this now if I simply press the name we see that we go to the page and I can probably swipe from here to go back which doesn't seem to happen but we're going to figure it out and fix it in a moment by defining it as a stack anyway to just go back just duplicate press R to reload the app and you're back here the problem is that right now the link only works when we click on the name of the exercise if we click on the container container it doesn't work we in fact yes I'm going to do it That's why I'm going to have a text component here again, because we want to navigate each time we press the entire container of an exercise, so what I'm going to do is wrap the entire view. the whole container inside the link like this link needs hre let's give it hre while remembering it's exercise okay something broke but at least I can press and it goes there something broke because by default the link is its own component if we want to represent the child. component as link We simply provide the link as a child property like this, the link is the only logical thing there and in the end it actually represents this exercise container with its styles.
Now the styles are fixed, but when we press this it doesn't appear. It's okay because as long as the link works as a child, the child should have its own press event, the press event to handle the press events when the user clicks on it, the problem is that a normal view doesn't have this activated. press event what we need to do is transform from a view to another component called pressable which is very similar to how a view works but at the same time it can handle press events, we can simply replace the view with a pressable and make sure that the label closing You can also press save and now if I press it it actually redirects because a pressable has this press event and behind the scenes because the link has this as a child the link will send and set the press event when that happens, will navigate to the barbell exercise, just like that, the entire container of our exercise list item is clickable uh, yeah, perfect, perfect, uh, the next step is the next step, on this exercise page , we need to know what exercise we landed on, we clicked on the tilt hammer calls or like Easy Bar Coral or what exact exercise we clicked on for that we need to send some data on the expert router uh the way we do it, especially in these situations in which we navigate to an item we don't want to send the full date about the item, that's a rule for navigating to different screens when we navigate from a list of items to the details screen, we don't want to send data about the item, we just want send identifiers and let the The screen handles the fetching of data and manages the data itself by knowing the identifier, so when I go to the exercise, we won't send if I open the data, we won't send the entire object like this. we will only send the name there and the page.
The Details page will handle the logic of fetching the data itself. How do we send the data? How do we have dynamic puff parameters to do it instead of in the file name instead of a normal exercise? name, I'm going to rename it and I'm going to use the square brackets and this represents a dynamic puff parameter, for example, if I name here what we're going to get, we're going to get here, uh, using a hook. imported from using local lookup parameters imported from export router we can access within our components parameters we can access this data which is dynamic we can access it here and the parameters will have a property called name because that's how we do it we call here and we can do console logging parameters maybe it's not even going to log them to the console.
I'm going to go into details of the exercise and then I'll say permanent. name, if I press one of these things, we see details of the exercise, exercise why, because that is the value that we are currently sending when we click on one of the elements we are redirecting to the barbell exercise and if I will do it here like um biceps bicep curl and if I'm going to press them, there's going to be a bicep curl here. The fact is that we want this to be a dynamic property coming from the element, so what I'm going to do is go from a normal position. string to a template string using a backspace flag, this is below the escape button and now we can, instead of the static string here, we can provide a dynamic puff parameter called element do name.
I'm not sure how the spaces will work there, but check that if I press incline hammer curls we see the exercise name incline hammer curls. I wonder on the web how this works. I think the link automatically encodes the URL, you know, because in a URL we can't have spaces. I can check it. just running it again on the web, go here and if I press, for example, the tilted hammer calls, yes, in fact, in the URL we are perfectly URL encoded, so it simplifies our job a little bit because I was already thinking about how we will work with a The name we will have to encode it in URL, but it does it automatically for us and in the details screen when we access by ram. naming it automatically decodes it and when we display it it shows as the element name so knowing the name what we can do here is we can do import exercises from asset data exercises, do Json and we can search, we can look more late.
Then we are going to query it from the database, but now we can simply make the exercise that we want to show will be inside the V array and we will find it by doing search and here if the element. The name is equal to the parameters. The name means that that is the exercise we want to display and because in some cases it may be missing if we provide a different URL, we will check to see if the exercise is null or undefined and simply return here. a text that says exercise size not found; otherwise we will return for example no par rams. name but exercise. name and maybe even exercise do something else, so if I do this we'll see a name but we can also access other things like type, let's say strength, what we can really do is start with some of the styles that we have here. with the exercise name and muscle equipment, so let's copy these text components from our exercise list item inside our details screen and replace our current text with these two text boxes.
We need a style sheet, so let's import a style sheet from react native at the bottom of This of a component, let's create them using the style sheet. create and here we are going to copy the subtitle of the exercise, the name and the subvalue of these three styles, let's copy them here and if I'm going to go to that thing, well, it shouldn't be an element, it should be a right exercise because here We are working with the exercise, so now if I press it, yes, it has some styles ready, yes, it has some styles and maybe add here a style in the view that renders the entire page so that it is called container in order. to add some space maybe to the whole page, come on, container, the container will have a pting 10, for example, okay, now it's better, as we can see, not only can we have static URLs, toowe can have dynamic path parameters and that's how a lot of web applications generally work, for example if you go to Twitter and you go to a user, a slash or something like that will appear on YouTube, that's the same thing and now we can do the same thing.
The same concepts, the same logic on mobile devices, plus having this dynamic property. What I wanted to show you now is how we can add a proper header that we're used to and be able to press return from here to the header that I have. I'm actually referring to Rea navigation from a stack browser. If we look at stack browsers here we see that tack gives us this UI where we can go to a screen then we can go back to it and it will also provide us with a header, I'm not sure why it's not shown here, it's normally sample, so how do we say that our application should be a stack browser?
To do this, we are using a special file called layout. Let's start by creating the underline layout. GS Like, I think I'll move everything to GSX for consistency, uh, yeah, and get back to our design. The layout is the file that wraps around our different screens, so the application, the layout inside the application folder, is usually called the root layout. and this layout will be displayed on every screen of your app. Typically the root layout is where, for example, we also configure global providers, but for now we only need to configure the browser we want to use for our application for these two screens. that we have, so let's first export a default function called root layout and if we don't return anything, we'll lose all our screens because like I said, the app layout wraps the components that we are R the screens all the screens that we're rendering, so that by returning null we are basically overriding the screens if you want to just render the screen we are on we are going to render a slot imported from the export router so by simply rendering a slot we are saying just render the screen and everything works we lost some styling, but okay, a slot just says "hey, render the screen", however, if we want to put this slot inside a browser like a stack, Browser, tab, Browser, drawer, etc., we can do that by importing here an Expo router stack component and rendering the stack here like this, we have a header, we can go there, we see the name, we can come back and we can navigate through it correctly.
Nice, uh, and I think now we can even uh. remove this white ghost because the stack has some background, the default background which looks better than my white ghost. uh your question might be fine now, but how can we adjust some of the things that we see here in the header, for example? like the title here the title by default is taken from our file name if we want to change it there are a couple of ways one would be instead of rendering a self closing stack here we can render by going into This we can render a stack closing, an opening and a closing and an inner path between the opening and closing stack we can provide a stack. screen components where we can adjust the settings of our screens the way it works is that we provide a name and the name must match the name of the screen we are going to for example index in this case and then we provide options , this comes from react navigation, so the screen options Where is Stack Stack Navigator?
Options here are all the options that you can provide to a Stack Navigator, for example, we can provide a title here, so if I provide here title exercises, we will see that the title of this screen changes to exercises. Another way to change the options of a stack screen is through the layout where we render them here, but we can also change them directly on the screen, so for example, I'll go to the name on the Details page of um, an exercise and here what I'm going to do is import the stack component from exper Outer from the exper router and just rendering this Tex somewhere in our UI stack, the benefit is that here we don't do that.
We need to provide the name because it knows what screen we are on and we can simply go to the options and give it a title here where title hello we see the title changes automatically. Another benefit of changing it directly from the screen is that we have access to data here, for example, that we can use for the title that we can use for the exercise. name and we are going to see the white grip barell curl here the name of the exercise at the top so we saw how we can use a different Navigator in this case we set up a Stack Navigator how we can change some options for different screens from the layout and also how we can change options directly from one screen now we have a two page application, um, yes, a two page component from which we can navigate from one to another And we see different information here on the details page besides the name, so I think a Details page is where we show more information about things that, for example, we can show in the exercise. instruction or instructions yes instructions like this we can give it a style like styles. in instructions instructions let's give it some styles here uh instructions instructions let's make the font size uh 16 let's make a line height I want to increase the line height a little bit to make it more readable, so I don't know, 20 is probably enough.
You can also increase the letter spacing, etc., but I think I'll leave it at that. I can also add them in different containers uh like so they look better, for example, I don't know the name of the exercise and the subtitle, let's put them together in a view like this and give it a name here Styles dot uh panel I don't know panel something so just have a white background color, a little bit of poding 10, maybe a border radius of 10 or five, yeah, I think it will look good and we can put the instructions also in another panel, so that they also have a white background and for the root container of our page I can give it a spacing of 10 to give some space between these different panels, so so we have them like this, we have instructions on how we should do them.
Yes, it looks good, but if we see this screen with a lot of data. we can't scroll through it, we can't scroll because we don't specify what we should scroll. Well, it's not that complicated to do because we can use a scroll view imported from React Native and we're going to use ourselves. We are going to replace the root view with a scroll view to say the whole screen here should be scrollable, now it is scrollable but we lost the space between the elements because the scroll view, if we want to provide the styling we will need the container style of content and now we have Gap again here and let's see how it will look here too, yes, I think it looks good, perfect, maybe for the panel like above the panel, should we add some text here with instructions, but I think it's clear as?
Well, the thing is, there is a lot of text. Do you want me to show you how we can add a see more and see less button? That can handle these types of situations. It's pretty simple with a few properties on the text component and a state variable, maybe you'll do it. I'm going to confirm everything first and add this simple read plus function, details screen exercise for the exercise, let me go ahead and show you how, first of all, we can reduce the amount of text that we display. here, to do that in a text component, we can provide here a number of lines and we can provide free lines to be displayed.
What I can do is below. I'm going to add a text uh C plus uh that will have some style styles. . C plus for C plus text I want to put it in the middle, so let's do Align, center align, we'll put it in the middle and maybe even add some padding to give it some space, maybe a font weight. like a 500 to make it bolder or even a 600 will look good okay the gray color yeah it's nice now every time I press S more I actually want to show all the lines there to show all the lines which I mean is if we provide the number of zero lines here it will show all the lines that are available if we provide a non-zero value it will show only those so by pressing this button what we want to do is change from three to zero and from zero to three again to do that, we need a state variable that keeps track of whether we expand the text or not.
A state variable in React Native is declared using a hook called Use State imported from React at the top. Here we're going to declare the is the expanded statement and let's make set is the expanded statement a very long but descriptive name and we're going to use this use State hook initialize with false because initially we don't want the statements to be expanded right here uh the syntax of the use The state returns us an array of two values, the first is the actual value of our state, the second is a function, a Setter with which we can update the value, let's go ahead and first use the value of our state, the value is this variable. call is expanded statement we will need that in the number of lines and we are going to use a tertiary operator to say that if your statements are expanded we want with a question mark we want to use the value zero because we want to show all the fields otherwise we want to show just three lines and if I go to the top and change here from false to true, we'll see that we're actually changing this behavior the way we want now, the only thing is when I press this button, we want to revert these expanded EAS instructions to do that in C, we can get more text.
The good thing is that a text has press events, so we can add a current event, here we have a function and update a state variable, we should always use the setter, we never directly update the variable, so let's expand the statement set is and we'll just take the existing value and revert it by putting the exclamation point in front just like if I press C more, it expands if I press again, it goes back to small, perfect, we see more, maybe the ping shouldn't be 10 , but five is enough and of course you can also change from C plus to C minus if it is currently. expanded so that you can go from a static string here C plus to a template to be able to execute JavaScript expressions, the JavaScript expression will again be a tertiary operation based on the value of the statement and expanded with a question mark we provide the value when this is right, when it expands we want to say C minus, otherwise we want to see see more now here we see more when we press we see that the label changed to C minus this is another conditional that is very useful to know how to use and so we have this logic and also we learned about state variables uh with a very simple example get perfect commit expansion instructions how are you guys?
Are following? I think we're ready, actually we are, yes we are. That's it and we're done with the first part of a UI related tutorial. We have set up a project with XO SDK. We use data D. We represent the list. We use the Expo router. We learned about it and also created the exercise. The details page in the next part will be where the fun will begin. In the next part, we will use IBM's steps and create a graphical API that will get exercises from an API ninjas API, so while we take a little break, you can go ahead and create an account on ninjas API, it's free, you don't need a card credit and also create an account on IBM staben, it's also free and you don't need a credit card, let me put this in the comments because I really want to go to the bathroom and while you do that while you create your account and get ready, I'll come back and we can continue, so yeah, I'll be back in a minute.
I'm back but I need a coffee, so I'll be back shortly because no, I'm back now. I have my second C for coffee. Okay for the second part of our tutorial. Let me check the comments. Can you explain to me about the slot? It's a little confusing. confusing uh so the shape is fine, let's see without the default layout without the layout uh without the layout file here by default the export router handles this layout for us when we add the layout, what happens if the layout fits our screens so I can think about uh, when rendering it, you can think about it like this, so we have a layout and then we have, for example, if we're on the home screen, we have an index screen.
Now the index screen, as you can see here, is secondary to the layout, but and when we are, for example, on the index screen, it looks something like this, when we are on the details screen, it could look like this details, so you can see that the screen we are on is a child of the layout component when router he will return null, that's whatwhich we're looking at right now, we actually want to say well, don't do it or null represents the screen that you want it to currently be on here, so that's where the slot comes in at the same time, we can't directly represent the index, we can't import into the layout index because it will render the index on each screen we need to dynamically render the screen we are currently on that we navigate to, that's where the slot is, it's the simplest way, it doesn't have any kind of browser, we can't go back by swiping left because that's a feature of a stack browser, so it's very, very simple, where it's useful to do that is, for example, if we needed a global provider or if we needed a global provider like I don't know, let's use the react context and we want to wrap all the screens that we go inside. to need the slot we are going to need the layout because like this it doesn't make sense because we can remove it and it will still work it is the same if it doesn't have it it is also useful when for example we want to provide user interface components that are shared between different screens for example by having a view here from react native and a style that has, let's say, some strange styles that you'll see like Ping 20 and red background color, and here a slot. and maybe even a flexible one.
You'll see that this view in the root layout is something that is shared between different screens in different slots here, so we see the red background with 20 dots on the home screen if we go. in the details screen we still see that one, that's where layouts are useful, layouts are useful for shared UI between different screens and also for sharing behavior, like some logic here listening to notifications, this is a behavior that we want to happen on all screens. right, do it in the root layout and we can put a stack here and it will look very strange having this background, but now by having a stack instead of a slot we have additional benefits.
I'm going to delete a view. I'm just going to leave a stack, you'll see that it works like this and in a similar way we can have other Browsers, for example tubs, if we simply change from stack to tubs, we'll see that we have two tabs at the bottom of the index and the name of the two screens. that we have here, so let me back up or maybe even let me get St. I hope this makes a little more sense. A slot that we use when we don't need a browser, when we just need any browser of some kind. of shared logic or maybe shared UI like a custom view or a popup that you want to share between everything and in any other case where we really need a proper Navigator like a Stack Navigator, a Tab Navigator, we are not using a slot.
We're using a stack here because behind the screens the stack is showing us the slot. Okay, let's see if we have any other questions. Are you thinking about updating Uber Eat? About Uber Eats. Uber Eats is actually a food watering app. We have been working very hard for the last two months and have prepared a pre-recorded, let's say we are going to publish directly to YouTube. That's an 8 and a half hour Zero to Hero tutorial that's going up very soon, it's 8 hours here and it's going to help you build, oh, I think it's going to help you build a food watering app similar to the full stack of Uber, it is very deep, as it covers both the front and the rear, it is built with a super base. and native R and Expo also has notification implementations in a two-sided marketplace where you have administrators managing users' dishes when the user completes it, it automatically sends updates in real time, so it's a great tutorial if you're interested, make sure to subscribe. the channel right now so we don't lose it in the future and uh yeah, we're going to post it in the next few weeks, in fact we have so much content planned that I don't know when to post it next week.
I have two or three videos coming, well, uh, publ es.saying that the V3 router looks great. I plan to upgrade from XO DK 49 to 50 soon I will update the navigation and I hope the upgrade doesn't break many things. I'm planning to maybe do a livestream exploring that and also showing how it can be updated. an older version of Expo DEC to the latest Expo DEC, but yes, the Expo V3 router looks very good, especially with API routes, it opens the doors to many new possibilities that were not possible in the past, now we can have full St applications written only in In fact, I started working on a new premium course focused on Re Native and Expo in the last few years.
Re Native and the Re Native ecosystem system has changed a lot and it's very exciting to see where it is at the moment, there are so many apps available. using Expo and in the top lists more than 1,600 apps are using Expo, that's from the research done by aan bacon, you can find it on his blog, but yes, nowadays a lot of things changed and I really want to update and create a new course . focused solely on native rack and Expo that will teach you everything you need to know to create mobile applications with these technologies right now, we are in the stage of planning the content and starting to record it and I sent your email a Sur. a survey that can help us shape the course if you haven't seen it yet.
I'll share the link here with you in the chat. You have some questions. We already have almost 200 responses, but yes. help me understand the topics you are interested in, the experience you already have so that I know what to focus on and what I could leave out and many other interesting questions that will definitely help us shape them. So yeah, if you're interested, let me paste the URL here in the chat. I would appreciate your help with this survey, very good guys, so let's move on and also if you are interested in a course that is currently active that will teach you how to build complete applications with Rack Native Expo and AWS amplifies our course in the academy. noas Dev is the way to do it, you can check it out not only in Academy.
Developer, you are welcome to join, we have weekly group training sessions and I would love to meet you there anyway. Go back to our tutorial because we still have three parts, and the second part that we're starting right now is a question about the Graphql API for that. like I said, we're going to use an API, I found it on the Internet API ninjas, it has an API for exercises, let me open it somewhere here, ninjas, you can create an account, they have three for free. level with quite a few API calls per month and you don't have to provide any credit cards in the future, maybe you don't actually need an API for these exercises, maybe you can create your own database of exercises, but I'm too lazy to This tutorial creates and defines my own exercises, so I prefer to use a data set that already exists, so they provide many APIs and one of them, if I look here, is called exercises. and if we send a request there, they give us the array that we already saw that we are already working with in our application, so if we scroll down, let's see how we can send a request here python JavaScript not Jaz.
I would really like to do it. look at an example of qu, which is a utility that helps us send get and post requests, let me switch to the code so you can see it better, but yes, we will do it together, from an architecture perspective, how everything is going. To make it work, as I said, we are going to create a Graphql API where we will combine different data sources, for example, the exercises that we will get from V API and then connect it to a custom database for our own data. and so on to do it the best way and the easiest way is to use IBM steps and because it simplifies many things to bring and create Graphql API especially when we have different data sources so Graphql API will be created with stepen and we're going to connect the ninjas API to uh to steps and invent from our native application.
We will simply consume a Graphql API. We will do everything step by step, so don't worry, it will be uh. It's going to make a lot of sense as we go, so let's go ahead and open staben as well, go to stab zen.com or follow the link in the description below and you can create a free account here as well. Let's go to us. There is no need to go to the panel, we need to go to the documentation, let's go to the documentation and let's go to install and configure, what we need to do is first of all, install the CI command called staben for that.
Let's run npm install DG to install it globally, then let's go ahead and do it in a terminal. I'll open it up here in Visual Studio code. I'll put it in full screen, so let's start installing. steps and CLI globally on our machine Carlos hello, you are good, so now it is installed, let's go back to the documentation and we need to create an account, go ahead and create the account, follow the link in the description below to do it. We will need the administrator key and the API key and the next step will be to log in within our CLI with our credentials, so let's go back to our terminal, follow the steps and log in and here we need to provide the account name. which you can find by opening the dashboard and here if you open the side menu the account name should be here or you can also go to the account where you will find the account name and the keys for your API. so for the account name, let's copy this account name from here, paste it into our terminal to get the admin key, go ahead and copy it from here.
I'm going to hide my screen a little. I'm going to copy the administrator key and the next St, yes, the next step is that you have successfully logged in with your account. You can also check who I am and we see that we are the account name, the name that we provided before Perfect, now our steps and CLI are ready for us. to start creating our um to start creating our Graphql API uh for that, let's go ahead and follow the documentation to the next teacher on the next page to transform a rest API to Graphql, that's exactly what we need because the exercise API It's a break.
API we need to transform into a Graphql API using staben to do it, it's super simple with the command line, it's one line of code and the line of code is called steps and we import curl before doing that. I'll start working first. with curl independently because after we have this curl request we can just put steps and import at the beginning and that will transform it and import it and create the graph API as simple as that like I said Coral is a simple command line tool to send send get and post requests, for example, what can we do with coral, the documentation is horrible, uh, for cor, but what I can do is check the URL that we need to send the request to.
Let's copy this URL, scroll down to the code example in API Ninjas, the fitness API. I'm going to check out the JavaScript documentation and copy a URL from here. Let's go to the terminal and clear the screen. Let's curl and then we're going to hit. the url oh my gosh corl and let's paste the url here now muscle let's make chest here why is it like this where can i take a coral request example coral request example i need a brother oh with headers so again let's start from the beginning we need cor and we need a URL that we want to request back to this uh I don't even know which one for JavaScript exercises V1 yeah basically it's not that complicated it should be https uh API API ninjas com exercises V1 and then We'll be able to add variables like muscle, etc., so let's just do the exercises on this simple URL.
We see that we are missing the API key. The API key. If we look at this example, this is a header with a name X API. key and here we have to provide the API key, the header for curl is sent with dashh and here we are going to write a script, we are going to provide this header with name X The API key inside a chain ring should be x- ai- key oh boy i need to remember how to work with curl ok. Okay, so dots and so on, and here we need to provide the actual API key, the API key that we can take from our API ninjas panel, so let's go to my account, my account and here is an API key, press show API key , copy it and let's go back to provide it here, let's see, press enter.
Gosh, it's very complicated to do it in the terminal, change this, try again and yes, it works now, so it's better to copy it and move it to a file by creating a simple text file here and pasting this Coral command, uh, if you want. make it multi-line, you can put the headers on a new line, but in that case you need to put a trailing slash to make sure this command is multi-line. Now I can copy the C command, open the terminal. sure, paste it and it should work, yes, try it and make sure it works.
Also remember that in the ninjas API documentation we saw that we can send, for example, a property called muscle if,for example, we add a question mark here that we can provide here. variables for example muscle can be let's say chest let's copy this muscle chest let's send it again and hopefully we'll see exercises for muscle chest only it has a lot of instructions but yeah type strength muscle chest yeah it works like that Similarly. by sending different parameters here we can query different types of exercises, uh I think that's it, it's a valid C command, once we have a valid C command we can copy, paste and we receive the results we want in that In case of that we can, we can transform it into an import command step by step to transform this rest API into Graphql API I and look how easy it will be, first of all, before we start, I will create in my folders uh in my project.
I'm going to create a new folder called API, this is where we will store all of our steps and API information. Let's open the terminal again and make sure to put the CD into the API folder to work there. I'll delete it and when we have a c command that we want to use, all we have to do is prepend steps to it, then import it and we're done. Now let's copy this same command with steps and import at the beginning, let's paste it into our terminal making sure we are in the API folder, press enter steps Z will ask us what we want our endpoint to be called, you can give it a name.
I'll leave a default one that it suggests and we see that in just a second or even less we import the data successfully. uh from this and created the Graphql schema. If we look in the API folder, we see two files and a folder. The first is configuration and specifies the name of our endpoint. The Graphql index is where we combine different um subgraphs of our. API in this case only includes the curl index graphql file if we go there in curl index graphql we see that it created a query that when executed will send the break request to the endpoint exercises, it has the muscle property and it also has some headers for our API token um.
Well, maybe it doesn't make much sense now, but let me show you, let me show you in action how it all works with just one step and the import command. We define the schema in the next step. is to deploy and run our API to do it again, it's as simple as running the steps and getting started, and this will deploy our schema to Graphql in the steps and to the cloud. Once this is done, we can push this API to explore our Graphql endpoint. Let's press on this API we're going to open it in the browser and here we have it maybe I'm going to put it at the beginning and if I just run this query we see some data but we don't see any return Why because here in the variables?
Let's see that we have a variable called muscle that we need to provide a suitable value, for example chest, if I do that we see that we get the data from the API, but the good thing is that compared to the rest of the API. This is a Graphql API and we can for example style the data we want to return depending on the page, for example in our mobile app on the home page we may only need the name Muscle and Equipment, let's leave the name as the first Muscle. as the second and Team as the second as the third that would be the design of a query that we would need on the home screen if I run that now our API only gives us the data that we designed and that we ask it to give and we see that it actually contains the only exercises we asked for for the chest muscle, how simple that was, it's always impressive to me, how easy it is to create a graphical API using steps and it was literally two commands, yeah, we.
I needed to make sure I had created this Coral request and I had to remember how to work with coral, but after we had a coral request we simply added the Import Zen step at the beginning. What happens behind the scenes is that the Zen step is sending a request. it is analyzing the data that it receives, it is introspecting this data and it analyzes it and automatically creates a schema for us the schema in Graphql the schema is what PO is Graphql because it represents the data, the data structure and the queries and the mutations that we can . execute, so we see that each exercise has a difficulty of type rope team rope and all this information we did not have to create the steps ourselves and we automatically cut it and equalize it and create it based on the response from the API API endpoint that we provide and now , when we send a request to our Stepen-hosted Graphql API, behind the scenes, Stepen is actually sending this request to the API ninjas and the result comes back to step Zen is being optimized and is returned to us later, with step and start , this schema that was generated is transformed into an actual graph API that is hosted and deployed in step and then literally in seconds, it's super powerful and it's also very extensible.
It's very flexible because yes, we can do it with a couple of commands, but at the same time we can adjust this schema any way we want, for example, instead of my query. I might want to change this to exercise and make sure this query is called exercises. If when you do something, Stepen automatically deployed it in 2.4 seconds, uh, because he saw that the file has changed now. If we go to the dashboard and if I refresh this in this interface, we can see it and press. in the documents we can press on the query and we see the query that we have called exercises, so we manually update what we want our query to be called.
Also the muscle here should be chest. Now we can query the exercises and it makes more sense in a similar way if we look in the documents, we see that yes, let's open the documents, press query type to see the query type and we see that the exercises query returns an array called root input . I'm not sure I can see it correctly. I'm going to do it like this, but as you can see here, it's an array called root entry, why since we didn't specify the name of that property, the nice thing is that we can always change that directly in the schema, so if the type root entry we will rename it to exercise and the return type here in the exercise query we will also rename it to exercise 2 access to this type Graphql will automatically redeploy we can go back to the panel we can refresh and we see that the query now returns an array of exercise now makes more sense, another thing is what happens if we want to add other parameters to our query.
If we look at our exercise API documentation, in addition to the muscle, we can also provide a name that can help us search for data. adding it to our Graphql as a parameter, it's as simple as adding it here as a parameter to this query name of type string, if we go back to our panel, maybe here, if we refresh, we will see that our exercise query has two parameters, name and muscle , yes that's how it is. The first time you work with Graphql let me show you how it works, for example, right now we can of course query the chest, but what if we are looking for a specific one?
Let's say I don't need all of them, I just need the name. What if we are looking for a specific push-up exercise? How can we search for it well? First of all because our query has a parameter called name, which means that here in the exercise query we can add a parameter called name and I can code it for, say, push-ups, if I search, we will see that we have three exercises that contain the word push-ups , pushups, bench presses and bench presses, the thing is that we don't want to code it, we want to be able to send a variable and this will make a lot of sense later when we integrate it with our UI because we want to send a dynamic variable to do it, we need to declare it . a variable in our query at the top and the variable here in the query should be prefixed with a dollar sign, let's call it name, we need to provide the value, the type of this variable and now it will be a string for the name property of our exercise query instead of hardcoding it, we're going to send the name of the variable, so that's where we have, that's why we have here the name without a dollar sign and here the name with a dollar sign because the name with a dollar sign comes from here. and here it just specifies the property name that we expect in our graph query.
Now if I run it, it will give me all the chest exercises, but in the variable field, if I make a comma here and add the name pushup, it will go to the name will be passed to this name here, this name will be passed to the name of the exercises parameter and we will send it to our rest API and back we will receive only exercises that contain your flex Name any question so far guys, is it clear? If we can, we can continue because yes, let me check, okay, yes, I think from an API point of view, our API, our exercise graph API is ready, so we integrate it with the rest of the API. transform it to an equal graph API using IBM's steps and the next step is to place this graph API inside our native application so that instead of using dami data here, we can query our API that we just created and we will query similar to as we play it here on the graph on Stepen's board, we'll define a query that we need, for example, on the home screen, we'll need the name and the muscle, that's what we're going to provide.
Let's run the query, uh, if a user doesn't search for something, we won't send any variables and maybe not even muscles so we can see them all. name muscle name muscle and so on perfect so that our The next goal is, instead of sending this query from our dashboard, we need to send this query from our native application before we do it. Let me go ahead and do a get status get commit get commit actually, maybe it's good to rename this as well. curl folder to let's say exercises and if you rename the exercises folder in the graphql index make sure you rename here also exercise to access the file correctly now let's check if everything is going correctly the file was deployed.
I'll double check if everything is working here by sending a request, yes I think so so now I can safely do a state g G ad oh come on get add get commit configure the Graphql API using IBM step Zen and that's it We don't need this one, okay. okay, okay, okay, so the next step is to query the graph API from react native to do that, let's use the react query library, let's open the react query documentation uh, it's a tanack library and it's a powerful library to manage and query data regardless of Graphql or Rest API in uh react and react native let's move on here is the react version version three uh which one should we use if we use the latest one and the latest one is yes let's use the latest one ? uh, Q chart, well, yeah, let's go to the installation overview, um and let's use, we'll start by installing the react query in our application.
Let's do it by copying the npm command to install tack cor query, let's install it. in our app, make sure you run this in the root folder, not in the API or something, it should be in the root and in the package. If I go to check, we should have a new query and version of T RCT in my in case the version is 5.17, let's move on. Next step, let's go to the quick start and this C sneaks in, okay, check out mutations, so one in re native, let's check out the re native documentation, we don't need anything from here, let's check out the Graph ql see documentation on Graphql I remember it was better. uh.
I also used Apollo client in many of my projects, but rect quer is also very good, so what other libraries do we need to install for Graphql? Thats what Im looking for. basic with Graphql request, probably Graphql request we need, okay, so let's get started. First of all, yes, we install the tack query. The first step is to create a client and wrap it around all our screens to provide this client to the other screens. and other components in our application, where we will do this. We will do it internally because we need a react query on all screens.
This is something we must provide globally. If you remember I said these things should happen in the root layout the root layout is where we create global providers because the root layout will span all the screens of our application so let's go ahead and start by importing some stuff from tack react query let's do the query query provider query client provider and what is the query client query client, the first step is to create the client, so let's create here a new query client and if yes, a new query client and then to have this client we need to make sure that we provide it to all the screens in our application to do that we are going to wrap our stack navigator inside a query client, let's close it at the end and we need to provide here the client that we created before, it is not supported because does not provide the props property, a query query client provider. here query client provider.
I made a mistake with the name, that meansEvery screen in our application, including for example the index, will have access to the qu client and will be able to request things to run queries. Okay, let's run a query for example, where do we need to query things? We need to do it on the home screen where we present a list of exercises right now. This list of exercises comes from dummy data, but we want to query it from our Graphql API to do so. We're going to use a hook called Use Query from tack RCT query and let's go ahead and make constant data with the same use Query and here we need to provide some options because okay, let's change the name from app to exercise screen, so yeah, because our exercise screen will be rendered within the layout, using the query hook will access the query client provider for the client we define here the Query usage, what the Query usage expects, it expects a query key, our application is closed, but yes, we will find out in a moment, it has a query key and the query key must be an array that identifies this query, for example, you can have in this case, it will be for us exercises.
The second option here should be the query function. The query function is the function that will be executed when we want to get the data, so it is a function that should return some data. For now, let's just return the exercises that also come from dami's data. Now the thing is that in our apartment. list we can go ahead and use the data here dot just data the nice thing is that the use Query can also have an is which gives us an easy loading property that we can check here if it's loading, let's just go back and activate the activity indicator component from React Native's react native activity indicator is a simple spinner.
Let's go ahead and restart our server to see what's going on here, let's open it up in iOS and see that if in the query function I'm going to return an empty array here, um. Let's not expect to see anything if instead we return the exercises from dummy data, we see the exercises because we are using the data in the flat list coming from the use query, so yes, that is the query function and the query T rect is independent of how it represents or how it gets data because only you only accept a query function which can be an asynchronous function and the way we get this data is really up to us and the react query doesn't care, the query it only cares about the data itself. it handles loading logic, it handles error states, it handles on device, caching and optimization but how we get data is up to us and we can use fetch API, we can use axos, we can use rest API Graphql, anything inside this query function.
That's why it's really powerful because it's agnostic and it doesn't force you to use some kind of API or anything like that, so in our case we don't want to use data from our dami data that we really want. check out our Graphql API that we implemented in Staben, let's see the example in the react documentation query how it works with Graphql in the Q graph, well you have this Q graph, well you have this request, the request comes from where the request comes from Graphql. Go ahead and install Graphql Request which will be a library that will help us send a request to a Graphql npm server.
I was npm install Graphql Request. Let's very quickly open the npm Graph C request to see, yes, that's what I was looking for because also. Graphql request we also need Graphql to specify um yeah, let's do the npm as well. I simple Graphql, you need Graphql and Graphql request. Okay, now we're going to import into our index screen, uh, two things, first we're going to import the gql, which is going to allow us to define the query string, the structure of our query with the fields that we want to get, we're going to import that from the Graphql request and we're going to define our query const uh or let's call it exercise query equal to using this gql which means graphql, we're going to follow it with a backtick and hit enter and this is where we're going to put the query that we want to run, we usually copy it from here , so copy the query from our dashboard and make sure that when you run it it works correctly, after that happens we can copy it into our Graphql query and we will be you, we will use it to send the request to to the server to do that in the query function we are going to use the graph request qu we are going to look at the query API T in the query function we need the request we need the URL we need the query document and the variables okay, the request is imported from the graph request , right, let's go through the documentation graph request again, yes, we destructure the graph request request and inside the query function of our use Query, we're going to return the request and here we need some options first of all. we need the URL URL, let's define the URL here at the top constant URL equal to something I'm going to put in a moment in addition to the URL, let me check the documentation, yes, it requests the URL and then the document, the document that we defined here with the top exercise query URL, let's find the URL that we need to send the request to, which will beIf you go to the tabs, that will be here at the top, you may not be able to copy the full URL here, but what What you can also do is verify that you can open the endpoints page and the one I am on. working with what it's called Suave, something this copies, so look for it in the endpoints and press copy URL, maybe in the documents where it's also no and go back and paste the URL here.
You can't qualify the property name as undefined, let's see why that means that. the request gave us an error, the error is handled by the R query, so we can check that we can take the error here and we can do another if statement here if it is not loading, but if it is an error, let's return a text that He couldn't recover the exercises. it's error handling, uh, what happened to the data, let's log the console with data, oh yeah, I think I know why if I log in with data and look in this one, it's loading, loading, I can't get the exercises back, that's true, I expected that, uh, and we can. do a console log error to see what is happening, the problem is that authorization is missing or not allowed, we do not provide the API key for the steps and because here if we look at the dashboard, if we look at the headers, there is a header called authorization, so let's see how we can send this header using Graphql request. uh, there's the fourth request header, uh headers.
Do we have a home page? Let me check and point out Van's options, yeah, let me do that here, so I think. in the request the next parameter is variables but we don't need any variables yet and the fourth one i think they are headers oh boy wait wait wait headers ask for headers in that case we should put them in an object with a document URL. variables and request headers, yeah, so let's put this into an object URL, uh, inside this one it's going to be called document document, uh, and we're also going to have header headers, headers something like this, request headers, yeah, request headers and the request headers I need the authorization header from staben and it will be the API key which of course you can provide via environment variables but I'll try it like this to see if it at least works and then we can think about how to optimize it . things can't recover exercises if I refresh uh we don't have an error nor do we see the flat list let's check the console to see the data because most likely the data has a bit the data is currently not an array the data is an object that contains the exercises, which is the name of our query, so in the flat list now we should simply say data, do exercises and so finally we have our data, our data obtained using uh graphql and we react to the query within our application.
To be honest, I think the Apollo client is a little simpler in terms of this, but yes, the r query is still powerful and if instead of sending a request like this, instead let's set up a Graphql client like we saw in the documentation, let me close the window because now it's better, so as I was saying in the Graphql request, for now what we did was just use the request method to send an ad hoc request. Another way would be to create a Graphql client to create a Graphql instance that we preconfigure with the endpoint and with um with let's say uh with the headers so that we don't have to do that every time, it will make a lot more sense, so I'm going to do in the source, let's make the graph or let's make in the source here the Graphql client.
GS and here we are going to import the Graph qu client from the Graphql request, so let's import the Graphql client, create the client using the Graphql client and here what should we provide? We need to provide the endpoint and the endpoint remember that was our URL. here, so I'm going to take the URL, I'm going to move it here and I'm going to say this is the endpoint and here we're also going to say we need some headers, oh boy, graphics client, let's look at the endpoint request we need the client and the client is and pointed out how we provide the headers.
Come on, increment, no, no, Gra, yes, it's in the headers here in the headers and we need to provide the headers that we had here, for example. authorization and so on. Oh, I forgot to initialize a new Graphql client. Now it makes sense and you also believe it correctly. What we can do is export this client, export the default client and on our page, let's go ahead and import the client from Graphql client and when we make a request, we're not going to make a normal request, we're going to make a client request in this case, we don't need to provide the endpoint, uh, and we don't need to provide the headers.
We only need to provide the document because we've set it up once and we can actually simplify this by immediately sending the query itself. If I go to refresh it still works and the query itself is much simpler and in this situation we can delete a URL from here we can delete a request um and yes it works better now and the dami data is no longer used so yeah , now our query looks much simpler, it has this, it has the query function which can also be simplified to this and it handles the error, the loading status and everything else is handled by the uh react query in the graphical client qu If you want, the good thing is to not provide or expose private keys within your code.
What we can do is provide this through an environment variable. Environment variables are working in Expo in uh since recent versions and what we have to do is create the EnV file and we have to create an environment variable that if we need to make it available in the client side code. We need to prefix Expo public and then the variable name, for example, uh. Graphql API key equals and let's provide this API key. This is the API key I have. I'm going to put in our environment variables and you may not actually need those codes and back in our Graphql client, I can take the same constant API key process.
Dot EnV in the environment variable name export the public Graphql API key. Now we can provide this API key here either by making a plus API key or by making a template string with inverted flags like this and now it won't be able to be retrieved because we need to restart our server for the environment file to take effect after it has been done, we can refresh and if everything works, the query should run and we should see the list of exercises back here. Yes, we have that if something doesn't work. make sure you console log the API key and make sure it's available because if it's not defined it will fail and you'll see that yeah basically if the value won't be defined it can't be retrieved so that was hard but that It was necessary because we had good.
Another thing is that on this screen in this query we not only need the name and the muscle, but we also need the right team, so let's add the team because we see that something. was missing from our screen, so the team, just adding it to our query string, we see it here in the team oh perfect, okay, okay, okay, what else? The next step the next step will be to query a specific exercise in the exercise details screen, so if we go to the name here right now, we are still using important data in the detailed screen to find the exercise, as I said, the rule of fum is to go ahead and use the identifier, for example the name of the exercise. to query the data about that exercise, the disadvantage of this API actually is that the data does not contain an id, so we can use the names to search for them, but I am thinking that in some cases, when just the name is not going to work . but we'll see, so let's go ahead and first of all, yes, open the details screen and here let's go ahead and remember what steps we need to follow to send arequest to the server.
Well, the first step is to import Graphql. from the Graphql request and to define our query document, uh, let's say query exercise to define it, we're going to use Graphql and we're going to open the post Tex to provide that document for the query itself here, here the rule of um Yeah, we follow Go ahead and design our query in the editor. Here in the Builder you can visually add the field you want, for example, we may also need the instructions on the details screen and also the equipment, so name the muscle instruction equipment, that's all. which we need right now from the variables we're going to need the name just so I can delete a muscle from here and I can delete a muscle from here we're going to use the name to send a request, for example, if I'm going to provide here a name, let's say push-ups, but I'm going to do more.
Yes, you will see that if I search for pushups we see three results, but if I go to do a 300 bench press, it will be an exercise with two exercises again, a little strange, but anyway this is the query that we will send on the details screen to get the details of an exercise, so let's copy the query document once we're happy with its structure. put it in our Graphql document here and in our component we're going to need to use the query hook, use the query query from the T cor query and we're also going to need the Graphql client that we created in the Graphql client, the Graphql client which has the endpoint and all the configuration needed to send a Graphql request.
Now we are going to get the data and it is loading and also the error while using the usage query in the usage query. Remember that we need to send an object with some. parameters one of them is the query key and this identifies and is used to cache the result and to invalidate the result when something happens a query key uh remember in the previous screen we called it where are the exercises? uh for the details of the exercises I recommend using a combined query key where the first part is still exercise and the second variable will be the name that comes from perams or maybe you can even structure the name here and use the name as the key, so that this is a combined query key and The benefit of having the same first exercise parameters will be that when we want to invalidate all the information about the exercises in our application, we can invalidate all the keys that start with exercises, but the second is the name and it must be so.
Because we want to cache different data for different pages depending on each page separately, let's provide the second query function and it should simply send a GraphQL client. request and we are going to provide this document here query exercise like this now what are we going to do uh we are going to do the next thing we are going to check here if it is loading, we simply return an activity indicator imported from react native that will show a spinning wheel, like this that if I go there, it shows the perfect spinning wheel. Where do I have perams?
Oh, here on this line, we actually don't need it anymore, because the constant exercise will be some of the data. from the response we got the data will be an object with a property that has the same name as our query in this case exercises so let's make data. exercises and that will be a matrix so we can perform the exercise in the zero position now, if I'm going to go here, we actually look at it and it really works, I'm not sure why it's the first one to do weighted pull-ups, this tells me, Oh. I know, I know, I know, I know, I know, uh, before you go there, make sure you always have this if it loads, then if it fails and only then try to render the data, so that if it produces an error, I'm going to show some text, let's say it couldn't fetch data like this, but why is everyone processing this one right first?
Because we send this request but do not provide the variable name, please do not confuse the name here, the name here is for the query key. which is related to the react query, this is how it handles caching on the device, the request that we are sending to our Graphql client is happening here and we need to provide it as um as variables and now we will provide it as name. if I go to press once, yes, now it works and it lets me refresh because it will make more sense if I press the first one, it loads, it shows if I press the second one, it loads, it shows if I go.
Back to the first one, it doesn't load anymore because it caches and remembers that this data is already on the client. You do not have to submit an application again. If we go to something new, it will do the loading state it will do. the que query if, however, yes, we go to something that is already in the cache because we are giving it a name, it works perfectly fine like that, and yes, that is how we have a Details page, perfect, we are not done yet . we want to do a search uh maybe pagination is important too so first let me go ahead and do a start state g G add get commit minus query M or react query or yeah let's query the Graphql API using query from perfect reaction, so yeah, we're at 3 hours.
I really want to stay under 4 hours, but we still have a lot of things to do. What I'm going to do, what I'm going to do, to be honest, should I do it right? We still have many things to do. things to do and we don't have a lot of time um something important is a fitness tracker here there are still a couple of things that we still have to look at at least and load more so we can get around and load more items let me put them here and if we have time at the end we'll do it but I really want to show you the

mongodb

integration and how we can track different sets and reps so in the bonus I'm going to have uh search and we're also going to have the load plus how's it going guys so far liim number one thanks um the question someone is asking when the food watering app is going down, it's coming soon guys in the next few weeks we just have to finish like the description thumbnail and post it right?
Guys let's move on to the third part and implement the exercise log functions. What we want to do is be able to record different sets of exercises and store them in a database for the database we're in I'm going to use mongodb if you're not familiar mongodb is a great nosql database that works with documents um when I was working on fum actually I used U fum I built fum on top of mongodb and I don't know it works very well for for this type of applications, because the schema is flexible, we don't have a strict schema, we can provide different documents with different types on the fly and it is quite powerful, together with mongodb Atlas, we can host and create a database very very quickly, but in fact before entering the database and so on, we still have to do some UI to add a new um to add so we can add a new uh what's a new set called so we're going to do it on this screen to add a new set let's go ahead and on the details screen right after the instructions let's create a separate component that will handle the logic of adding a new assembly in components, let's create a new file for the input of the new assembly. point at the entrance.
GSX I'm going to define a default component here that will simply render some text and on the details screen let's go ahead and after rendering the view, the panel for our instructions, then let's go ahead and render the new input set for me. it was automatically imported at the top here from our components folder, what we see is we see the new set input uh component there and let's go ahead and also start working on this component which will be responsible for adding a new set of this exercise. I will import the Style Sheet to define the styles using the style shit. create create and here I'm going to have a container uh which will be the styles of a full container for this, you probably need a white background color to match the styles of the rest of the containers uh and a container of five or how much we set there, let me see the panel, the panel has pting 10 and border radius five.
I'm going to copy them from here to have the same style. Well then what do we need? Well, we need two inputs for the uh for the reps and for the weight and we need a button to insert it, an input in native is rendered using a react native text input component. I'm going to delete some text here or maybe let's add a new set or record, let's make a simple record set next that we add a text entry with a placeholder, uh, reps and another one with a placeholder weight. We see them here and we can go ahead and add some styles. input and we'll also know what I'm going to delete the text here to simplify this component and only have two things because now I can put the text inputs on the same row just by providing justify, not justify content, but the flexible address row. in the container now the Ws and the weight are on the same row and if I provide some styles to this input, like border with one or one, it's too much, you can make the style sheet. capillary line with what is the smallest border we can have uh if we add a ping like 10 if we add a space in the parent component to manage the space between them if we also make a flexible one in the input that will make the input take half the space or share the space between that and what else what else between that uh, I'll make a border with a border radius of 10 to make them round. 10 is too many, five perfect.
I love it, maybe the border color should be the border color should be. gray or wins borrowed or if it's wins borrowed I think the wi should be higher yeah now I like it so if I do two three now perfect it works in addition to the input we need a veyor button so let's use a component of RE native called button, let's render after our text inputs and the button has a title, the title is added, this will generate a native button and because it is a native button it will look different on IOS and Android.
A native button in iOS is just text with this blue color. on Android it has a real background, so if you're working on Android and it looks different, that's fine, that's how it's supposed to be. That's the power of react native, it represents native components, uh, and by pressing, we need to add the set that we need. call a function call add set this will be an arrow function where we will do a console war add set so if we go to this one and press add we will see a console warning at the bottom add set the problem is which right now we don't have, we can't access the values ​​that we provide in these two fields because as we have them now, this is called uncontrolled input, which means we don't control it, it manages it on its own and we don't have access . to the value to create a controlled input we need state variables for that we are going to import the state U of react and we are going to define two variables, one for the set of representatives, the representatives use the state and another for what is called weight weight and set weight use State the state will be a string uh and when we send it we are going to transform it into a number now let's go ahead and bind the state variables with our inputs to bind it we need to provide two values ​​one of them is the value of a St of a text input should match the value of our state and the text change when changing text uh when the text input changes the text when it detects that the user changes the text we want to update Repeats by calling the set repeats in the same way as we will do it with a second one for the weight, but in this case we will provide the weight and set the properties of the weight.
Now we can still write, but the good thing is that now we can access these variables in the ad set function and we will be able to send them to the database, we see ad set 343. I'm not here, let's send it or save it. data in the database, but in the end what we're going to do, we're going to set the reps back to an empty string and we're going to set the weight to an empty string as well, so after we hit add, we're going to reset these values. Okay, another thing is that when we open the keyboard right now it doesn't have digits it has letters we can specify what type of keyboard this text input is uh so type the keyboard type it's going to be numeric or numeric uh it should be numeric yeah, now it's numeric and the same thing for the weight, okay, so they both have numeric values, okay, um, that means now we have a UI, when we press the ad set we want to save things in the database, for that we really need a database, go ahead. and do git add git commit minus M new set input UI and let's go ahead and see how we can create and configure our database like I said we are going to use mongodb and we are going to use mongodb Atlas to host our mongodb server in the cloud very easily, let's go ahead and you can try it for free, it's free, it offersa free solution, so everything we are doing here is free.
I'm going to log into my account, let me remember. my credentials and after logging in to the cloud. mongod to.com you will go to your projects, maybe you don't have any projects, but in my case I have a couple of them here, so what I'm going to do is click new. project and let's go ahead and give it a name, our project will be called training, let's create next and here I will add my self as the project owner, let's click on create project, once this is done, we need to create a deployment that we need. let's deploy a cluster for our database, let's click on C and on this page we can choose how we want to deploy it.
Go with m0 which is a free version, it is perfect for learning and exploring mongodb in a cloud environment. My zero cluster name is already used so I'm going to use cluster free and I'm going to use AWS and let's just click create deployment now uh uh this will automatically add our AP as a whitelist so only we can connect to it and he will do it. It also allows us to create a database user, it automatically pre-populates the username and password. This is going to be important, so let's go ahead and open some notes or open a file and provide the username and password here.
Remember them because we might need them later, just write them down and let's click Create Database User. Now let's go ahead and choose a connection method for now, we don't need to connect anyway, we are going to access our data from the browser, so let's do the Data Explorer. here and before you press, review the setup steps and press Done, our data is being deployed so it may take a little time. If I'm going to deploy your data cluster for free, I'm going to reload this page, it should take about a minute or two to set everything up and get our cluster sample data set loaded successfully, which means if I'm going to go to the deployment database here, we will see that our cluster is being deployed.
I think it should be implemented. click on the cluster itself and here we can go to collections, collections are database tables, in very simple words a collection is a database table of data, it is called different because it is not a table because it is not it has a structure but anyway the collection here we have different databases in our collection and we have different tables here we have some sample data but what I'm going to do is create a new database specifically for our use case , The name of the database. call it workout, the name of the collection that we are going to record sets just when you go to the gym, you perform a set that you want to record, so let's call the collection sets and additional preferences, we don't need anything, let's create and now.
Below the collection we will see a new database called trainings and a new collection called sets. It doesn't have any data but we can insert a document. Let's press Insert Document and here we can specify key value fields for our document. I need the name of the exercise exercise, for example, push-ups, push-ups or whatever it's called, we have something like um chest send request, yeah, the name of the exercise, push-ups, I'm going to use it here to say that, hey, this is going to be, we're logging in um rep for the exercise called push-up, let's press this plus sign to add a new field and the new field will be reps, how many reps the reps are not a string, so let's change here from a string to an integer because the repetitions be a real whole number, for example, eight repetitions.
I'm going to do a plus sign here for the weight again. It won't be a string, but it won't be an integer either. I think it should be a double because you might like it. I could add some weight, like I know 35 five, so you can have 7.5 here, for example, after we have this, let's press insert and the document will be inserted and we'll see it here. Maybe you can duplicate it or clone it and say, "I'm going to do another one with uh just six reps but in this case I'm going to increase the weight and I'm going to insert it and now we see that we have two documents here so yeah, now that we have a couple from docs, let's go ahead and continue integrating this into our application in our Graphql API.
If we look back at our implementation and our architecture, we know that our Graphql API is already connected to the exercise data source which comes from a rest API and We also want to connect mongodb to the same Graphql API so we can query from our application a single endpoint, a single graph Q API for all the data needs that we have with Staben, that's actually the power of Staben because taben. allows you to connect different data sources in the same Graphql API, this is very powerful because in many cases the data we have comes from different sources and as you can see in this diagram we have a Graphql created with Stepen.
Created from different building blocks, you can connect with SQL backends from some data with rest apis from some data like backends with rest or without SQL or even with other Graphql apis, so that's the power of um Stephen. I'm going to show you a step. Mongodb blog post on IBM website created by Carlos uh and here he shows step by step how we can integrate uh mongodb with um with stepen. I'm going to go ahead and do it with you and what we need to do first is on the atlas side, we need to enable the data API.
The data API is basically a rest or rest endpoint on top of our database so we can interact with mongodb by sending rest API requests. We know that with Stepen we can easily integrate with the rest. apis because we have done it with the API for our exercises before, right now the data API is disabled so let's go ahead and enable it, we will select the data source here so there are no clusters and that's it, let's enable restricted access to the data. API why are we going to update, let's select the free cluster, enable the restricted AI API.
I access that access to the project access manager, maybe I need to change no, no, no, no, what's going on there, let's go to the atlas. I'm going to go to the training data. API and let's enable the cluster without enabling why I did that before and it was working perfectly fine, maybe I need uh this Advanced to enable why it's restricted and disabled. Ask the organization owner to add your IP address to the IP access list for atlasi. I think it's sad that it was added not only so my IP probably wasn't added correctly but in the previous one it was added so I'm not sure why this happened.
Now it's loading, you need to configure the IP access list if I'm not mistaken. like it should be added automatically, but I'm going to see maybe it couldn't be added automatically when I created it by default, it's being added as the IP you're accessing from automatically, maybe somehow the VP changed, no, uh , but where do we add this? I learn more includes your current IP created as part of the automatic configuration, let me check my access to the database I, oh, I think, where, where, where, let's try using the quick start to add our IP entry, yes, it's already there , I think I need to specify what you have access to to cancel the plugin, oh boy, where was that edit?
Remember I had to change the search steps and TB maybe the blog post will show that API for kids data mongodb API Atlas Data API Manager organization access uh or uh requires app let's go to the organization settings configuration organization name required no Federated not required IP access list for atlas, maybe I need to enable this to allow me to purchase IP. It is saved? Yes. Let's now go back to our training and try to enable it again. Oh, the maximum number of operations for the Product Data API is one, okay. another project I was testing with API is fine, that was test two.
I'm going to go ahead and leave the project. I need to remove the old configuration. uh, let's disable it for the previous one. You don't have to do that. I was testing it before and it looks like Atlas, let's go to Save and now I reload it, yes, it's saved and I can continue with our training project by going to the data API. Hopefully it will work now. We narrow our search. Refresh this page. Let's enable. No, again, it's working, no, it's not possible, look guys, I think I'm going to work with an older API that I created because I just can't enable it here, but it should work for you, if it's the first one, then my previous one. one is completely the same, but it has this data API.
Hopefully I'll be able to enable it in the settings, enable data API saving, so after that has happened we'll have a URL endpoint that will allow us to interact with our mongodb API through this. URL in the database here I have the same one that we created in the previous one, the only difference is that this is called group one and in the collections of collections I have workouts and I have series here with the same data like WPS and weight, so let's go . to the data API and see how we can send a request, let's press this, test your API and create your we need to create an API key, let's give it a name and the name is going to be set because we are going to interact with stepen's vcpi let's generate this and let's copy it and save it to a file uh uh, so let's copy the snippet, we will query the cluster, the database called trainings and the collection called sets, after setting this up, we can copy the cor command that was automatically generated for us and we will go to a terminal to test it by just pasting this C request and sending it, we see a document with ID because we are sending a request to find one, let me paste this request here because instead of sending a request to the action find one, let's send a request to find to find all the repeats of repeats that we locked in the database, not just one of them and I'm going to delete the projection here because the projection is specifying which fields we want to return, in fact we want to return all of them and when I delete the last row make sure to also remove the comma because otherwise it will fail and what else I think that's all, let's try to copy it. again and send it from the database and what do we see, we see the documents.
Inside the array you have ID, you have pushup reps and weight exercises and if you are going to add more close, also if the API is not working with this data. API, you will see the data source cluster. Make sure to change here from no access to read and write. It's important to have access to that. Now I'm going to go to the database to create one more element in our training set collection, let's duplicate this and do 10 reps with five weights inserted now we have two elements and if I'm going to send the Cal request again to all elements , we will see two objects return from the URL of the from query collection sets now, what does that mean?
It means that if we have a c request we can prepend steps to it and import and by running this command we will parse it and add it to our steps in the graphics API. For that, what we need to do is first move to the API directory and here in the API directory, let's run the steps and the C command. I'm going to press Enter and we'll see that there is an unsupported flag location, this location, um. let's remove it from the cor command, we don't need it and I'm going to copy it again and paste it here starting starting done that's it now if we look in our API we see another folder created called curl that has the index and here in this we see our query for my collection which send the request to the endpoint and so on, if our steps and start are still running it will work automatically but if not we can run the steps again and start.
I see that it's working and it's deployed automatically, so I can go to the steps and the dashboard and I can do an update here. What I'm going to see is a new query called my query where I can provide the collection here, the collection, uh, the collection. The collection is configured, the database is training and the data source is group one and for the documents I can do exercise identification and representatives, let's try to send the request. I don't need the variable name here, unexpected void in the query exercise, my query sets, etc. in what database trainings let me check the request, there are collection sets, collection sets, oh I know what I don't need here, the parentheses if I don't have any variables, now we have inflections and all that other stuff, uh, the stuff. is that I don't want to have to configure the collection, the database and the trainings etc., what I want is for it to be automatically enabled for us.
We can do this by setting it in our schema that was generated for us first of all, instead of my query I want to set sets, then instead of having variables for the collection data source etc. insteadof that, I will provide after the headers, I will provide the body of the post, which should be a string and a string with triple codes um uh triple codes and here we need to provide an object where we have a collection of codes and the collection should be sets and not with a double code set, then we have the data source set to Cluster one or cluster three in your case or cluster zero and the database is going to be exercised.
The last one doesn't have the comma so pay attention to the structure and now we can go ahead and remove the variables from this query because I don't I don't need it now, let's see if Stepen implements it successfully, yes, I can go back and I can refresh, refresh to see and I can go to the Generator. I see the new query called sets in the docs. I can take representatives of identification and waiting exercises, I can send it. I don't need the name here and this is the query that is connecting to a mongodb and taking the data from V.
Let's go ahead and copy this query and go to this page, where I'm going to go and create a new component for which we render a set list for that, let's go ahead and create a component called list or set list in GSX, let's do a rack native functional export and let's go into our details screen after we have an input, let's render. We see the list of sets here and we will have to make a query here to obtain the data from our Graphql API. Constant set query is equal to Graphql and here we provide the query we created in the dashboard.
Let's import Graphql from T, not from T. query but Graphql request and also import the query using the T query and also import what the Graphql client is called from the Graphql client in our component. Let's go ahead and do the constant data query with the same query usage and here we're going to have a query key called set and a query function that will be used by the Graphql client. Make a query. Request and the document we want to request is the set query. Yes, we can have an error as always, it is loading and if it is loading, the activity is returned. indicator and here let's do console log data to see the data we get.
If I go to the details page, we see the sets document and it has object and perfect object, which means here I can go ahead and render a flat list directly from react. native where the data will be data points, set a point if you saw that there were also documents, then the documents um and render the element, we're going to get the element here and we're going to render a text component. just saying element point uh weight or better element do reps X element. weight, so if I go here we will see the two representatives that are queried from our database.
Another way will be to add a variable to this request to get only the representatives for this exercise for now. Yes, that will be it. The white background color will also have a vertical margin 10 and a poding 10 and a border radius five, maybe a vertical margin five, just border radius and hidden overflow, so yeah, we also have the flat list here that shows a list of entries. Last thing, I really have to finish this before we hit the 4 hour mark, but there is one thing we didn't implement by adding a repeat, so I think the best way is to provide this in the asset pack that you will download and there you will i will provide the source code with the details of the last step where you will see how you can add a set to the database anyway we have eight minutes maybe i will manage it but i don't think so let's try to do it eh but anyway during hours, Mark, I can't go over it because YouTube punishes everyone for it, okay, okay, okay, let me see how we can send an endpoint data API by testing our API, let's see, let's see. the documents and in the documents custom HTTP and authentication authorization data point um API Examples insert a single document and inserting a single document is a subsequent request, let's try to copy it from here, let's try to move it here and we will see what the API is.
It looks like I'm going to zoom out a little bit, so I'm going to copy the API URL from the previous one to the action and I'm going to change it to this one to have my AP API and after the action I'm going to insert one after that is the subsequent request API Key API Key I'm going to use this API key this content type accept uh and data data source group one uh collection set database training document will be exercise push weight two four and Representatives, let's try to send this request Cel to see if it works.
I will do it like this inserted, yes, it is working. That means I can do a step and import steps and import and try to do that, make sure they are in the API directory, hopefully that will work, a cor snippet expected, that's what I'm going to remove for the location, let's do it again, ok there is a problem with the cor, while checking that the given C command is valid it will work yes it is working but why it is not working with the steps and import oh it is not Json it should be the inserted Json application , okay and let's check in the panel that if I update we will see that if I update it should be a correct mutation API.
Because? Is it a query? It should be a mutation for those steps and is coupled by generating a mutation when using the default graph operation type. It is a query to change the previous import to mutation. Men will update the scheme to mutation. Alright. I can do it manually in C. 01 from query type to mutation uh of ok and the type here should not be root, it should be insert uh insert set response and I'm going to use insert response instead of root here, okay, now it's being implemented and I can check here, if I update in addition to the query, I can also add the mutation and the mutation here will be called my query.
I can add inside the collection called what are the sets called, sets, database trainings, what's the other one? a group of data sources one and the document will be the document will not be a string or will be a string the document input document here is uh It's complicated name name hi Yes, we actually need this the document anyway guys I'm going to provide information in the asset package, so be sure to download it again in a couple of hours. I'm going to let you know that I really have to close this one right now, also the source code you will find in the description of this video, so everything will be there for you to see and finish the last steps.
Anyway, we have managed to do a lot of things. We integrated it with a rest API we created our own database we created the Graphql API we learned about Expo Ract Native, expert router we did a couple of screens so it's really a lot we managed to do in these four hours I hope you enjoyed guys If you you made sure to subscribe to the channel, thank you very much Stepen for sponsoring this video and I have to close it right now. Well, I'll see you next week with more tutorials. Make sure to follow.

If you have any copyright issue, please Contact