The provided text meticulously documents the creation of a full-stack reminder application. It begins by outlining database schema migrations for “users” and “reminders,” followed by establishing API routes with corresponding controller functions. The explanation details the implementation of a service layer to handle business logic and interact with data models, incorporating input validation using Zod middleware and robust error handling. Finally, the text guides the development of a React Native frontend, demonstrating data fetching with TanStack Query, component creation, state management, and the implementation of CRUD operations for reminders, culminating in a functional mobile application.
React Native Development Fundamentals Study Guide
Quiz
- What is the primary benefit of using a step-by-step guide during a coding tutorial?
- Explain the role of NodeJS in React Native development.
- What is the purpose of npm init in a project setup?
- Describe the function of the Express framework in the context of backend development.
- Why is it considered insecure to hardcode sensitive information like API keys directly in your application code?
- What is an environment variable, and how is it typically used in a NodeJS application?
- Explain the concept of database migrations and why they are important for managing database schemas.
- What is the key difference between raw SQL queries and using an Object-Relational Mapper (ORM) for database interactions?
- In the Model-View-Controller (MVC) plus Service pattern, what is the responsibility of the service layer?
- What is a middleware in Express, and what is its typical use case in handling requests?
Quiz Answer Key
- A step-by-step guide provides a structured and predictable path for learners to follow, ensuring they don’t miss crucial steps and can replicate the instructor’s actions more easily. It also serves as a reference point for troubleshooting and review.
- NodeJS is a JavaScript runtime environment that allows developers to execute JavaScript code outside of a web browser. In React Native development, it is essential for running the Metro bundler, which compiles and packages the JavaScript code for deployment on mobile devices.
- npm init is a command used to initialize a new Node Package Manager (npm) project. It creates a package.json file, which keeps track of project dependencies, scripts, name, version, and other metadata.
- Express is a minimal and flexible Node.js web application framework that provides a robust set of features for building web and mobile applications. It simplifies tasks such as routing, middleware integration, and handling HTTP requests and responses.
- Hardcoding sensitive information directly in the code exposes it to potential security breaches if the code repository is compromised or accessed by unauthorized individuals. Environment variables offer a more secure way to manage configuration by keeping sensitive data separate from the codebase.
- An environment variable is a dynamic named value that can affect the way running processes will behave on a computer. In NodeJS applications, they are commonly used to store configuration settings like port numbers and database URLs, keeping them separate from the main codebase for security and flexibility.
- Database migrations are version-controlled changes to a database schema. They are important because they provide a structured way to evolve the database over time, ensuring consistency across different environments (development, staging, production) and allowing for easy rollback of changes if necessary.
- Raw SQL queries involve writing SQL statements directly to interact with the database, offering fine-grained control and potentially better performance for complex queries. ORMs provide an abstraction layer, allowing developers to interact with the database using object-oriented code, which can improve readability and development speed for common operations.
- In the MVC plus Service pattern, the service layer contains the core business logic of the application. It receives requests from the controller, processes data (often interacting with models), and performs operations before returning a response back to the controller. It separates concerns and promotes reusability.
- A middleware in Express is a function that has access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. Middleware functions can perform tasks such as request parsing, authentication, logging, and error handling before or after the main route handler.
Essay Format Questions
- Discuss the benefits and drawbacks of using raw SQL versus an ORM for database interactions in a web application development project. Consider factors such as performance, development speed, maintainability, and team expertise.
- Explain the significance of implementing the Model-View-Controller (MVC) plus Service pattern in backend development. How does this architectural approach contribute to code organization, maintainability, and scalability of an application?
- Describe the role and importance of middleware in the Express framework. Provide examples of common middleware use cases, such as request parsing, authentication, and error handling, and explain how they enhance the functionality and structure of a web application.
- Outline the process of setting up a basic NodeJS backend for a React Native application, including initializing the project, installing necessary dependencies like Express, and configuring environment variables. Emphasize the best practices for managing project configuration and security.
- Discuss the fundamental concepts of React Native navigation using a library like Expo Router. Explain how to define routes, navigate between screens, and manage layouts to create a user-friendly mobile application experience.
Glossary of Key Terms
- API (Application Programming Interface): A set of rules and protocols that allows different software applications to communicate and exchange data with each other.
- Backend: The server-side of a web or mobile application, responsible for handling data storage, business logic, and API endpoints.
- Dependency: An external library or package that a software project relies on to function correctly.
- Endpoint: A specific URL that represents a resource or functionality exposed by an API.
- Frontend: The client-side of a web or mobile application, responsible for the user interface and user experience.
- HTTP (Hypertext Transfer Protocol): The foundation of data communication for the World Wide Web, used for transmitting requests and responses between clients and servers.
- JSON (JavaScript Object Notation): A lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate.
- Middleware: Functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle in Express.
- Module: A self-contained unit of code that can be imported and used in other parts of a program.
- npm (Node Package Manager): The default package manager for the JavaScript runtime environment Node.js.
- React Native: A JavaScript framework for building native mobile applications for iOS and Android.
- REST (Representational State Transfer): An architectural style for designing networked applications, relying on stateless servers and standard HTTP methods.
- Route: A defined path in a web application that maps a specific URL to a particular handler function.
- Schema: A blueprint or structure that defines the format and types of data.
- Server: A computer or software that provides services or resources to other computers (clients) in a network.
- State (in React): Data that can change over time and affects the behavior and rendering of a component. When state changes, the component re-renders.
- UI (User Interface): The means by which a user interacts with a computer system or software application.
- URL (Uniform Resource Locator): A web address that specifies where a resource is located on the internet and the protocol used to access it.
Briefing Document: React Native Full Course – Backend and Frontend Development
Document Date: October 27, 2024
Sources: Excerpts from “01.pdf”
Overview:
This document summarizes the main themes and important ideas presented in the provided excerpts from a resource intended to guide users through building a functional React Native application with a backend API. The content covers setting up a NodeJS backend with Express, database integration using PostgreSQL via Neon, basic API endpoint creation, structuring the application with MVC+Service pattern, data validation using Zod, error handling, and the initial setup of a React Native frontend using Expo Router and Tailwind CSS.
Part 1: NodeJS Backend Setup and Fundamentals
Main Themes:
- Hands-on Learning: The core philosophy is learning by doing, emphasizing practical coding experience to build a functional application.
- Structured Course: The presenter introduces a comprehensive React Native course developed by Vadim, highlighting its detailed guides, videos, and educational exercises.
- Step-by-Step Guidance: A downloadable step-by-step guide is provided, which will be used throughout the tutorial. This guide will be updated based on user feedback.
- Backend with NodeJS and Express: The tutorial starts with setting up a NodeJS project and using the Express framework to build the backend API.
- Basic API Endpoint: The initial setup involves creating a simple “Hello World” API endpoint to demonstrate the fundamentals of routing and server responses.
- Environment Variables: The importance of using .env files for configuration, especially for sensitive information like port numbers and API keys, is emphasized.
- Nodemon for Development: The use of nodemon (implied through the –watch flag in the npm run dev script) for automatic server restarts on code changes is introduced.
- API Testing with Insomnia: The presenter recommends and demonstrates the use of Insomnia (or similar tools like Postman or Bruno) to test API endpoints.
Key Ideas and Facts:
- The course aims to take users from writing their own code to having a functional app they can showcase.
- “everything ties together and um yeah witnessing that by writing your your own code and then again at the end you will walk away with a functional app that you can uh show to whoever you want and say yeah this is what I’ve built”
- The presenter is a software developer with several years of experience, a former startup CTO, and a former university instructor in software engineering.
- “I am a software developer i have quite a few years experience in this field and I am already only like let’s say six plus years u startup CTO and co-owner um then I was also former and university instructor in software engineering”
- A detailed React Native course with workshops is available for enrollment.
- “it has everything that you need to know about React Native completely everything in very very much detail with the huge guides and videos so if you are considering if you are looking for a well ststructured course in React Native I highly suggest you to check it out”
- A step-by-step guide for the tutorial can be downloaded after providing a name and email.
- “after clicking on this link you’ll need to provide your name and an email and we’ll send this guide that I will show you in a second uh to your email address so then you can reuse it anytime you want”
- NodeJS is a JavaScript runtime that allows executing JavaScript outside of the browser.
- “as I mentioned already in the presentation NodeJS is a JavaScript runtime that allows ows us to execute basically JavaScript outside of the browser”
- npm init is used to initialize a new NodeJS project, and npm install <package-name> is used to install dependencies like Express.
- “just run npm in it and that’s it”
- “now that we installed it we need to uh run mpm install express”
- ES6 modules can be enabled by adding “type”: “module” to package.json, allowing the use of import instead of require.
- “we will be enabling uh the EA6 uh modules which is in my opinion very neat it’s going to make the code a bit more readable and uh let’s say more modern uh so to do that we simply need to pass the type module in our package.json”
- Environment variables, stored in a .env file, are accessed using process.env.<VARIABLE_NAME> and should be protected from being committed to version control.
- “hard-coding configuration values like port numbers is quite bad and especially uh hard coding and inside not in the environment file but uh adding let’s say somewhere here inside the application your API keys is horribly bad because it’s very insecure are instead we use environment variables for that basically uh env file”
- The npm run <script-name> command executes scripts defined in the scripts section of package.json, allowing for shorter commands like npm run dev to start the server with specific configurations (e.g., using .env file and watching for changes).
- “if I run to run our server the only thing I need to do is say npm run and then specify the name of this script”
- .gitignore file specifies files and folders that should not be committed to Git, such as node_modules and .env.
- “in this file we specify which uh files or folders from our um from our application we do not want to push to versioning control and usually these are the files that we can configure easily ourselves or very let’s say uh private files like environment so one example would be node modules”
- API testing tools like Insomnia are used to verify that API endpoints work as expected.
- “there’s many different API to testing tools like one of the most important ones is probably a postman uh now in the recent times it’s getting like they have a lot of functionalities it’s kind of over complicated ated at this point uh to start with but you might see it quite often also insomnia is very popular one”
Part 2: Database Integration with PostgreSQL and Neon
Main Themes:
- Database Necessity: A database is essential for persisting and managing application data.
- Serverless PostgreSQL with Neon: The tutorial opts for a serverless PostgreSQL database hosted on Neon due to its popularity and suitability.
- Database Types Overview: A brief overview of self-hosted, managed, and serverless database options is provided.
- Raw SQL vs. ORM: The tutorial chooses to use raw SQL queries for database interactions, emphasizing the importance of understanding SQL. While ORMs (like Drizzle or Prisma) offer benefits, raw SQL provides a better foundation.
- node-postgres Library: The pg library (node-postgres) is used to execute SQL queries and manage database connections in NodeJS.
- Database Connection Configuration: Database connection details are stored as an environment variable (DATABASE_URL) for security.
- Connection Pooling: The pg library supports connection pooling, which is beneficial for performance.
- Database Migrations: Migrations are introduced as a way to manage changes to the database schema in a version-controlled and structured manner. The tutorial manually simulates migrations by creating SQL files with timestamped names.
Key Ideas and Facts:
- Neon is a serverless PostgreSQL database used in the tutorial.
- “for this project right away I’m saying like we will use a serverless database uh posgrade SQL as well and we’re using posgrade SQL because it’s probably the most popular I would say and it’s very good so yeah that’s that but let’s really uh quickly cover all of the t like not all but main types that you might encounter of databases”
- Raw SQL queries are favored for this learning project to ensure a strong understanding of database interactions.
- “today we will be using raw SQLs because well this is a learning project and I believe and I I would argue like very harshly that it is a lot better to understand SQL and it’s a lot more valuable to learn that uh than simply relying on an RM”
- The pg library (npm install pg) is used for interacting with the PostgreSQL database.
- “in order to uh like write these uh SQL queries we need a library for that and we will use um install pg uh I mean pg which basically stands for posgress and this is the most commonly library it’s called node posgress”
- Database connection string from Neon is stored in the .env file as DATABASE_URL.
- “we will need to add this connection like this so we will say uh we are creating a new uh environment variable called database URL”
- Migrations involve up functions to apply schema changes and down functions to revert them.
- “here we are creating two different functions one is going to be down called down and the other one is going to be called up and this usually means we are migrating up and or we are migrating down”
- The example migration creates a users table with id, name, and created_at fields.
- “in the up we are what we’re trying to do is creating a new table in our database so what we’re doing here we’re saying okay create table basically create a new table if it doesn’t exist yet because if it will exist it will not create and the name of the table the is called users”
- Another migration creates a reminders table with fields like id, reminder (text, not null), notes (text, nullable), completed (boolean, default false), and user_id (integer, foreign key referencing users table).
- “now we need to do the same for reminders and now we can try to write this uh reminders code or like migration ourselves so first of all what are we doing we’re importing the database from and we will say okay so let’s import it from config and database and adds very important unless it’s got otherwise it’s going to throw an error for you okay now that we imported we have two functions well one of them is called uh up”
- Foreign key constraints ensure data integrity by linking records between tables (e.g., reminders.user_id referencing users.id).
- “we will add a user ID which is going to be an integer and it’s also very important to say that it will reference the users table and the ID field of that table and it’s also very important to say on delete cascade we’ll talk about it in a second but it means that if the user is deleted all of his or her reminders will be deleted as well”
Part 3: Building the API Endpoints and Structuring the Backend
Main Themes:
- CRUD Operations: The tutorial focuses on implementing Create, Read, Update, and Delete (CRUD) operations for the reminders resource.
- API Endpoint Design: Standard HTTP methods (GET, POST, PATCH, DELETE) are used for different actions on the /reminders resource. Endpoints for getting all, getting by ID, creating, updating, and deleting reminders are defined.
- Route Separation: To improve maintainability, routes are separated into individual files (e.g., remindersRoutes.js) within a routes folder.
- MVC+Service Architectural Pattern: The backend is structured using the Model-View-Controller (MVC) pattern with an additional Service layer. This promotes separation of concerns.
- Models: Handle database interactions (executing SQL queries).
- Services: Contain business logic and data processing, interacting with models.
- Controllers: Handle incoming requests, call service methods, and send responses back to the client.
- Middleware: Express middleware functions are used to perform tasks before reaching route handlers, such as parsing JSON request bodies.
Key Ideas and Facts:
- API endpoints are defined using Express router.
- “we will need to import router but also from express and router is what allows us to create these separated routes very nicely”
- The app.use(‘/reminders’, remindersRoutes) mounts all routes defined in remindersRoutes under the /reminders path.
- “now we can say that router dot slash uh without saying this reminders part router slash id then once again like this and like this so now it’s not yet finished we need to have one last adjustment so now if we go to our index file and inside here at the top we’ll import these routes so it’s called reminder routes and we are importing them from and they’re imported from actually it’s only one routes reminder routes.js”
- The MVC+Service pattern enhances code organization and maintainability.
- “to solve this issue we will be creating a new folder called routes and this folder will keep all of our routes separated so for example we have reminders routes so we will say reminders routes.js you can have let’s say user routes.js and you can even like have as many as you need and it will keep everything very clean and structured”
- Controllers receive requests, extract data, call service methods, and send responses.
- “the controller will handle these requests and send back the responses to the user well you can right away understand that it’s kind of like a waiter in a restaurant so it’s the one that will take the order from the user which is a request it will pass this order to the kitchen to basically create whatever was ordered which the kitchen is in our analogy a service layer and it brings back the prepared dish which is going to be the response to the user”
- Services contain the core business logic and interact with the database through models. They can also perform data sanitization and other processing.
- “this service layer which is as I said is kind of like a kitchen inside a restaurant which is responsible for the logic and the actual processing of the data so the kitchen the service layer takes the order from the controller a waiter and processes it prepares the food based on the ingredients a model”
- Models are responsible for executing database queries.
- “there is models layer which only communicates with a database uh in our like code example but in a kitchen example you can think of model like an ingredientre different ingredients to make those dishes”
- express.json() middleware is used to parse incoming request bodies as JSON.
- “express doesn’t parse the incoming data to JSON by default so we need to enable that by like basically passing the the middleware and the middleware ware it’s also um yeah let’s say what is let’s talk about what is middleware in general middleware is kind of a helper functions that help you process the requests before they reach the routes”
- Example model functions for reminders include getAll, findById, create, update, and delete. These functions execute raw SQL queries.
- “let’s create our first model which is going to be called reminders model.js and in here we will import our database connection and then we will start defining our functions”
- Service functions call the corresponding model functions and can include additional business logic (e.g., data sanitization).
- “in here we can import the model uh in here we just go import yes reminder model and also don’t forget to add.js and now let’s start using them well first of all the yeah the first one is going to be very easy we don’t need to pass anything we don’t need to do anything it’s simply return reminder model get all and we get all of these uh reminders and return them right away”
Part 4: Data Validation with Zod
Main Themes:
- Data Validation Importance: Validating incoming data is crucial for ensuring data integrity and preventing errors.
- Zod Library: The Zod library is introduced as a schema declaration and validation library for TypeScript.
- Schema Definition: Zod schemas are defined to specify the expected structure and types of data for reminders (e.g., reminder, notes, completed, user_id). Separate schemas are created for creating and updating reminders to reflect different validation requirements.
- Validation Middleware: A custom Express middleware is created to use the defined Zod schemas to validate incoming request bodies. This middleware checks if the data conforms to the schema and returns appropriate error responses if validation fails.
Key Ideas and Facts:
- Zod allows defining schemas as TypeScript types with runtime validation.
- “for this we will use a very popular library called zod so let’s install it by running npm install zod”
- Schemas define the expected data structure, types, and constraints (e.g., required fields, string lengths).
- “what we are saying here is that we are expecting an object and this object should have a property called reminder which is a string and it should have at least one character in it so it cannot be an empty string”
- Separate Zod schemas can be defined for different operations (e.g., creating a reminder vs. updating a reminder).
- “now we need to define different this is our main basically object schema that we have in our database for these reminders and here I said uh yeah no so for these reminders so it has an ID reminder notes all of these fields basically but now we need to define a separate schemas for when we’re trying to create and when we’re trying to update”
- The validation middleware uses the .parse() method of a Zod schema to validate the request body.
- “this middleware will receive uh in here the request response and next … this middleware will try to call the schema that we passed and parse it with the request body”
- If validation fails (ZodError), the middleware extracts and formats the validation errors into a user-friendly response with a 400 status code.
- “if the library is a zod error it means the request body did not match the schema that we were expecting so that means that we will try to build this error message in a human readable way … and then we’re returning the error with status 400 and saying that the data was invalid”
- The validation middleware is applied to specific routes before the controller function using router.post(‘/reminders’, validateData(createReminderSchema), remindersController.create);.
- “before calling this function we will add a validate data and we are also need to if you remember pass the schema to this validate data function”
Part 5: Custom Error Handling
Main Themes:
- Consistent Error Responses: Implementing custom error handling ensures that the API returns consistent and informative error responses to the client.
- Custom Error Class: A custom CustomError class extending the built-in Error class is created to include a statusCode property.
- Static Error Messages: Using constants for common error messages (e.g., “Reminder not found”) promotes consistency and simplifies future changes or internationalization.
- Error Handling Middleware: An Express middleware is created to catch errors that propagate through the route handlers. This middleware formats the error response, including the status code and message.
Key Ideas and Facts:
- A CustomError class allows for passing a specific HTTP status code along with the error message.
- “what this code does is we are creating a constructor our own class which will extend the error class that we already have here … but because we this error class does not have a status code we will call this and we’ll say the status code will be the status code that we provide in when we’re calling our custom error”
- Defining error messages as constants in a separate file (errorMessages.js) improves maintainability.
- “what a lot of companies are doing they create these constant static error messages and they reuse them that’s a very good practice of doing that it prevents the typos it keeps the code very clean consistent and later on you can even translate everything all of these very easily”
- The error handling middleware checks for a statusCode in the error object and uses it to set the HTTP status of the response. If no status code is found, it defaults to 500 (Internal Server Error).
- “this error handler receives the error and it checks like okay does the error have a status code … if it has it will apply it if it doesn’t it will throw 500”
- Route handlers use the next(error) function to pass errors to the error handling middleware.
- “instead of calling right away this error we will say call next and we already uh saw this next and it means that call next middleware or yeah or router or whatever”
- The error handling middleware should be the last middleware registered in the Express application to catch errors from all preceding middleware and route handlers.
- “you need to add this middleware as the last one … because if like as I said like it’s calling the next middleware so it’s going to call this one after the routes”
Part 6: React Native Frontend Setup with Expo Router and Tailwind CSS
Main Themes:
- React Native with Expo: The frontend is being built using React Native with the Expo framework, providing tools and services for development, building, and deployment.
- Expo Router for Navigation: Expo Router is used for file-system-based routing and navigation in the React Native application.
- Tailwind CSS for Styling: Tailwind CSS is integrated for rapid styling using utility classes.
- Basic Project Structure: The frontend project follows a structure with source, app (for screens and routes), and components (for reusable UI elements) folders.
- Path Aliases: Path aliases (@/) are configured in tsconfig.json to simplify import paths.
- Layout Component: A root layout component (_layout.tsx) is used to define a consistent UI structure (e.g., headers using Stack) that wraps around different screens.
Key Ideas and Facts:
- A new React Native project with TypeScript and Expo is created using npx create-expo-app@latest –template tabs@50.
- “now we are going to wait a second it created it so now we can go to our VS code on file open recent uh or no actually open and then we are going to go to uh documents projects and here we should have apple reminders clone let’s open this project”
- The frontend application is started using npx expo start.
- “click on terminal new terminal and in here simply write mpx expo start”
- Expo Go app can be used to preview the application by scanning a QR code provided by expo start. Simulators can also be used for development.
- “if you’re using Go if you’re using Expo Go simply scan this QR code and you will right away see the application on your phone just as easy as that no setup nothing for me as I mentioned I will be working with a simulator just to show it uh on the screen”
- Expo Router is installed using npm install expo-router react-native-safe-area-context react-native-screens.
- “we’ll be installing now the Expo router for our navigation as mentioned so to do that … we need to install all of these dependencies and actual exper itself”
- The main entry point in package.json is changed to app to use Expo Router’s file-based routing.
- “inside here where it says main and right now it’s index j index.ts TS which is here we need to say okay we will change it and now we will uh use the export router entry which is going to be the app folder in a way”
- Tailwind CSS is installed and configured in the frontend project using npm install -D tailwindcss postcss autoprefixer && npx tailwindcss init -p.
- “we will use Tailwind CSS for styling and I’m a huge fan of it and I use it in all of my projects and it really speeds up the development a lot so let’s install it by running this command uh we’ll do it with npm”
- A tailwind.config.js file is created to customize Tailwind CSS.
- “now that we installed it we need to initialize it and create our tailwind config file by running this command”
- The global.css file is modified to include Tailwind directives (@tailwind base, @tailwind components, @tailwind utilities).
- “now we need to go to our styles folder and inside global CSS we need to add these three directivs”
- Tailwind CSS classes can be directly used in React Native components’ className prop via react-native-tailwindcss.
- “to make it work what we need to do is we need to import tw from react native tailwindcss … and then we can use className prop in our elements”
- The _layout.tsx file in the app directory defines the root layout for the application, often using Stack from expo-router to provide header navigation.
- “in order to think of the um in order to showcase how it works we can create this layout file and let’s create it inside the app and let’s make it layout tsx … inside here let’s return and let’s return a slot from uh actually not a slot stack will be a better example let’s return a stack from I didn’t close sorry didn’t close the tag from react uh expert router and right away after I save you can see this header”
Part 7: Fetching Data from the Backend in React Native
Main Themes:
- Fetching Data: The frontend needs to communicate with the backend API to retrieve and display data (reminders).
- fetch API: The built-in fetch API in JavaScript is used to make HTTP requests to the backend.
- Service Layer in Frontend: Similar to the backend, a services folder is created in the frontend to house functions that handle API calls, promoting reusability and separation of concerns.
- Displaying Data in Components: Fetched data is displayed in React Native components (e.g., ReminderListItem).
- Passing Props: Data (reminder items) is passed down from parent components (e.g., the screen displaying the list) to child components (e.g., ReminderListItem) using props.
Key Ideas and Facts:
- The fetch function is used to make GET requests to the /reminders endpoint of the backend API.
- “now what we need to do is we need to get our URL the same way as we were doing inside insomnia so for example let’s we’re trying to get all reminders so let’s copy this go back to our code and let’s say okay let’s call uh this basically function”
- Response from fetch needs to be parsed as JSON using .json().
- “yeah this response should be parsed to JSON”
- Frontend service functions encapsulate API call logic and return the fetched data.
- “creating a services folder inside source and inside this services we will provi provide create reminders or maybe reminder service.ts and in here we can like create all of these different functions that will have all of the logic and that we’ll be able to reuse”
- Data fetched in a screen component is passed as props to the ReminderListItem component to render individual reminders.
- “we will have a reminder list which will map through all of the reminders that we fetched and for each reminder it will render this reminder list item component and very importantly we will pass down each reminder as a prop”
- Props are accessed in the child component through the props object or by destructuring. Types can be defined for the props a component expects to receive using TypeScript interfaces or types.
- “this is how we pass the data by simply adding this as an attribute but now in the child component which is reminder list item how do we receive it well we simply define here uh curly braces and we say props and now inside here I can access this data by saying props dot reminder”
This briefing document captures the initial stages of building a React Native application with a NodeJS backend, covering the fundamental setup, API creation, database integration, data validation, error handling, and the initial structure for the frontend. The focus is on practical, hands-on learning with a structured approach and separation of concerns through established architectural patterns and best practices.
React Native Course: Backend Setup and API Basics
React Native Course and Resources
1. What is this course about, and what will I learn? This course is a comprehensive guide to learning React Native. By following along and writing your own code, you will ultimately build a functional app. The course covers everything you need to know about React Native in detail, including guides and videos. It also includes educational exercises after each lesson to further enhance learning.
2. Who is the instructor behind this course? The instructor is a software developer with several years of experience in the field. They have a background as a startup CTO and co-owner for over six years and previously served as a university instructor in software engineering. The instructor identifies as a developer first and an educator second, emphasizing learning through hands-on experience and a desire to share their knowledge.
3. Is there any supplementary material or a step-by-step guide available for this tutorial? Yes, there is a step-by-step guide available that accompanies this tutorial. You can download it by following a link provided in the description of the live stream or potentially near the video title. After clicking the link, you will need to provide your name and email address, and the guide will be sent to you. This guide includes introductions to the topics and the tech stack used. The instructor also mentions updating the documentation based on feedback.
4. What is the tech stack used in this initial setup? The initial setup focuses on the backend using: – Node.js: A JavaScript runtime environment used to execute JavaScript code outside of a web browser. – npm (Node Package Manager): Used for managing project dependencies, such as installing frameworks and libraries. – Express: A minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. – pg (node-postgres): A PostgreSQL client library for Node.js, used to interact with a PostgreSQL database. – dotenv: A library used to load environment variables from a .env file into process.env.
5. How is the backend project initially set up? The initial setup involves the following steps: – Ensuring Node.js is installed on your machine. – Creating a new project directory. – Navigating into the new directory using the terminal (cd). – Initializing npm for the project (npm init). – Installing the Express framework (npm install express). – Enabling ES6 modules by adding “type”: “module” to the package.json file. – Creating a source folder and an entry file index.js within it. – Writing a basic Express application in index.js to listen on a specified port and return a “Hello World” message on the root route. – Starting the server using node source/index.js.
6. What are environment variables and why are they used in this project? Environment variables are dynamic named values that can affect the way running processes will behave on a computer. In this project, they are used to store configuration values such as the server port and later, database connection details. The benefits of using environment variables include: – Security: Sensitive information like API keys and database passwords are not hardcoded directly in the application. – Configuration: Different environments (e.g., development, production) can have different configurations without changing the code. – Best Practices: Hardcoding configuration values is considered insecure and bad practice.
A .env file is created to store these variables locally. The dotenv library is used to load these variables into the Node.js process. The .env file is also added to .gitignore to prevent sensitive information from being committed to version control.
7. How is API testing introduced in this tutorial? The tutorial introduces API testing using a tool called Insomnia (though alternatives like Postman and Bruno are also mentioned). Insomnia allows you to create and send HTTP requests to your backend API endpoints and inspect the responses. The process involves: – Downloading and installing Insomnia. – Creating a new project or collection within Insomnia. – Creating new HTTP requests (e.g., GET, POST) with the appropriate URL (including the correct port). – Sending the requests and observing the responses to verify if the API endpoints are working as expected.
8. What is the purpose of database migrations in this project? Database migrations are changes to a database schema that are version controlled. They provide a structured way to evolve the database over time, ensuring consistency across different environments. The tutorial demonstrates creating migration files (with timestamps and descriptive names) that contain SQL code to modify the database schema, such as creating tables and defining their columns. The process involves writing “up” functions to apply changes and “down” functions to revert them if necessary. While the tutorial simulates migrations with individual .js files and direct execution via Node.js, it mentions popular migration tools like Knex, Sequelize, and Prisma that automate this process in real-world applications.
Serverless PostgreSQL with Neon for a Reminders App
The tutorial focuses on setting up and configuring a PostgreSQL database using a serverless platform called Neon for a full-stack Apple reminders clone application.
Database Choice and Types:
- The application uses PostgreSQL, a popular relational database.
- The tutorial briefly discusses three main types of databases:
- Self-hosted databases: Require manual installation, configuration, and maintenance, offering full control but demanding significant expertise.
- Managed databases (e.g., RDBS): Cloud providers manage backups, scaling, and maintenance, suitable for constant high traffic but can be expensive if not optimized.
- Serverless databases (e.g., Neon): Fully cloud-managed, automatically scale based on demand, and offer a pay-as-you-go model, ideal for startups and unpredictable workloads due to ease of setup and cost-efficiency, including a free tier.
- Neon is the chosen serverless PostgreSQL database for this project due to its ease of use, elimination of maintenance tasks, automatic scaling, and a generous free tier.
Setting up a Neon Database:
- The setup process involves navigating to the official Neon website, creating a new account, and then creating a new project.
- During project creation, you need to provide a project name (e.g., reminders API), a database name (which can be left as default or specified, e.g., reminders_database), and select a region closest to the target audience.
- After creation, the Neon dashboard provides a connection string that will be used to connect the backend application to the database.
Database Connection Configuration:
- The tutorial utilizes the pg (node-postgres) library, a common and performant library for executing SQL queries in Node.js, which also supports connection pooling.
- For secure configuration, the database connection string obtained from Neon should be stored as an environment variable. This is done by creating a .env file in the root of the project and adding a variable like DATABASE_URL with the connection string as its value.
- Hardcoding sensitive information like the database URL directly in the application code is strongly discouraged due to security risks.
- The .env file should be added to the .gitignore file to prevent it from being committed to version control systems like Git, thus avoiding accidental exposure of sensitive credentials.
- The database connection is established in a dedicated configuration file (e.g., db.js inside a config folder). This file imports the pg library and creates a connection pool using the DATABASE_URL fetched from the environment variables using process.env.
- A test function can be included in the configuration file to verify the database connection by executing a simple query (e.g., SELECT version()) and logging the result.
Database Migrations:
- Database migrations are introduced as a crucial practice for managing changes to the database schema in a version-controlled manner. This ensures consistency across different development stages and environments.
- While popular migration tools like Knex, Sequelize, and Prisma exist, the tutorial opts for a more manual approach to illustrate the underlying concepts.
- A migrations folder is created in the src directory to house migration files.
- Each migration file is typically named with a timestamp followed by a descriptive name (e.g., 1678886400000_create_user_table.js).
- Each migration file exports two asynchronous functions:
- up: Contains the SQL code to apply the database changes, such as creating tables and adding columns. The CREATE TABLE IF NOT EXISTS command is used to prevent errors if the table already exists.
- down: Contains the SQL code to revert the changes made by the up function, typically by dropping tables (e.g., DROP TABLE IF EXISTS users).
- The tutorial emphasizes the use of raw SQL queries for database interactions to foster a deeper understanding of SQL. Examples are provided for creating users and reminders tables with specified data types, constraints (like PRIMARY KEY, UNIQUE, NOT NULL, DEFAULT), and foreign key relationships (REFERENCES with ON DELETE CASCADE).
- Migrations are executed using Node.js by running a script that loads the environment variables using dotenv/config and then executes the up (or down for rollback) function in the specified migration file.
- The tutorial demonstrates how to run a migration to create the users table and then the reminders table. It also shows how to roll back a migration by running the down function, effectively dropping the reminders table as an example.
In summary, the database setup and configuration in this tutorial involve choosing PostgreSQL hosted on the serverless Neon platform, securely configuring the connection using environment variables, and managing database schema changes through manually created and executed migration files using raw SQL queries.
Neon PostgreSQL: Database Table Creation via Migrations
The sources discuss creating database tables primarily within the context of using database migrations with PostgreSQL on the Neon serverless platform. Migrations are described as version-controlled changes to the database schema, allowing for structured management of these changes across different environments.
Here’s a breakdown of the process based on the tutorial:
- Migration Files: Database tables are created through migration files located in a migrations folder within the src directory of the project. Each migration file typically has a timestamp and a descriptive name, like 1678886400000_create_user_table.js.
- up and down Functions: Each migration file exports two asynchronous functions:
- up: This function contains the SQL code to create the database tables and add columns. The tutorial emphasizes using raw SQL queries for this purpose. The CREATE TABLE IF NOT EXISTS command is used to ensure that a table is created only if it does not already exist.
- down: This function contains the SQL code to revert the changes made by the up function. For table creation, this usually involves dropping the table using DROP TABLE IF EXISTS.
- Creating the users Table (Example): The tutorial provides an example of creating a users table:
- CREATE TABLE IF NOT EXISTS users (
- id SERIAL PRIMARY KEY,
- name VARCHAR(100) UNIQUE NOT NULL,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- );
- This SQL code defines a table named users with the following columns:
- id: An automatically incrementing integer that serves as the primary key (SERIAL PRIMARY KEY).
- name: A string with a maximum length of 100 characters, which must be unique and cannot be NULL (VARCHAR(100) UNIQUE NOT NULL).
- created_at: A timestamp that defaults to the current timestamp when a new record is created (TIMESTAMP DEFAULT CURRENT_TIMESTAMP).
- Creating the reminders Table (Example): The tutorial also demonstrates creating a reminders table:
- CREATE TABLE IF NOT EXISTS reminders (
- id SERIAL PRIMARY KEY,
- reminder VARCHAR(255) NOT NULL,
- notes TEXT,
- completed BOOLEAN DEFAULT FALSE,
- user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- );
- This SQL code defines a table named reminders with these columns:
- id: An auto-incrementing integer serving as the primary key (SERIAL PRIMARY KEY).
- reminder: A string with a maximum length of 255 characters that cannot be NULL (VARCHAR(255) NOT NULL).
- notes: A text field that can be empty (TEXT).
- completed: A boolean value that defaults to FALSE (BOOLEAN DEFAULT FALSE).
- user_id: An integer that establishes a foreign key relationship with the id column of the users table (INTEGER REFERENCES users(id)). The ON DELETE CASCADE clause specifies that if a user is deleted, all associated reminders will also be deleted.
- created_at: A timestamp that defaults to the current timestamp (TIMESTAMP DEFAULT CURRENT_TIMESTAMP).
- Executing Migrations: These migration files are executed using Node.js scripts. The script typically loads environment variables (including the database connection string) and then calls the up function of the specific migration file to apply the schema changes to the database. Similarly, the down function can be called to roll back the changes.
In summary, creating database tables in this tutorial involves defining the table schema in migration files using SQL CREATE TABLE statements within the up function. These definitions include specifying column names, data types, constraints, and relationships with other tables through foreign keys. The migration files are then executed to apply these changes to the PostgreSQL database.
ExpressJS REST API Route Definition
The source discusses defining API routes within the context of building a REST API using ExpressJS. Here’s a breakdown of how API routes are defined according to the tutorial:
- Basic Route Definition: API routes are defined using the methods provided by the Express application instance (app). These methods correspond to HTTP request methods like get, post, patch, and delete. For example:
- app.get(‘/reminders’, (req, res) => { … }); defines a route that handles GET requests to the /reminders path.
- app.post(‘/reminders’, (req, res) => { … }); defines a route that handles POST requests to the /reminders path.
- Similar methods exist for patch and delete requests.
- URL Paths: Each route is associated with a specific URL path. The tutorial uses /reminders as a base path for operations related to reminders.
- Handler Functions: Each route is also associated with a handler function that executes when a request matching the route and HTTP method is received. These functions receive request (req) and response (res) objects, allowing you to access request data and send responses back to the client. Initially, these handler functions directly sent back simple text responses.
- Passing Parameters in URLs: To retrieve specific resources, like a reminder by its ID, the tutorial demonstrates how to pass parameters within the URL using the colon (:) syntax. For example, /reminders/:id defines a route where :id is a parameter that can be accessed within the handler function using req.params.id. The tutorial also shows how to parse this ID to an integer if needed.
- Separating Routes with Express Router: For better organization and maintainability, the tutorial introduces the use of Express Router. This involves the following steps:
- Importing the Router from Express: import { Router } from ‘express’;.
- Creating a router instance: const router = Router();.
- Defining routes on the router instance instead of the main app instance: router.get(‘/’, (req, res) => { … });.
- Exporting the router: export default router;.
- Importing the router in the main application file (index.js): import reminderRoutes from ‘./routes/reminderRoutes’;.
- Mounting the router on a specific path using app.use(): app.use(‘/reminders’, reminderRoutes);. This means that all routes defined in reminderRoutes will be prefixed with /reminders.
- Associating Routes with Controllers: To further structure the application logic, the tutorial introduces the MVC (Model-View-Controller) plus Service layer pattern. In this setup, the route handlers in the route files (reminderRoutes.js) don’t contain the main business logic. Instead, they call functions defined in controller files (reminderController.js). This keeps the route definitions clean and focused on routing requests to the appropriate controller functions. For example, a route like router.get(‘/’, reminderController.getAllReminders); associates the GET request to /reminders with the getAllReminders function in the reminderController.
- Handling Request Data: The tutorial explains how to access data sent with the request:
- URL Parameters: Using req.params to access parameters passed in the URL (e.g., req.params.id).
- Request Body: For POST and PATCH requests that send data in the request body (e.g., for creating or updating reminders), the req.body object is used. However, it’s highlighted that Express.js needs middleware to parse the request body as JSON. The express.json() middleware is used for this purpose: app.use(express.json());. This allows accessing the JSON data sent in the request body.
In summary, the tutorial advocates for a structured approach to defining API routes using Express Router to separate route definitions, associating these routes with controller functions for handling logic, and using appropriate methods to access request data. This structure promotes a more organized and maintainable codebase.
Full-Stack Reminders Clone: Implementing CRUD Operations
The source material discusses implementing CRUD (Create, Read, Update, Delete) operations within the context of building a full-stack Apple Reminders clone using React Native Expo, Express.js, and PostgreSQL. The tutorial emphasizes a structured approach using a REST API with ExpressJS on the back-end.
Here’s a breakdown of how CRUD operations are implemented according to the source:
1. Defining API Routes:
- API routes are defined using methods of the Express application instance (app) that correspond to HTTP request methods:
- GET for reading data (retrieving all or a specific reminder). For example, app.get(‘/reminders’, …) to get all reminders and app.get(‘/reminders/:id’, …) to get a reminder by its ID.
- POST for creating new data. For example, app.post(‘/reminders’, …) to create a new reminder.
- PATCH (or PUT) for updating existing data. For example, app.patch(‘/reminders/:id’, …) to update a specific reminder.
- DELETE for removing data. For example, app.delete(‘/reminders/:id’, …) to delete a specific reminder.
- For better organization, Express Router is used to separate route definitions into dedicated files (e.g., reminderRoutes.js). These routers are then mounted on specific paths in the main application (index.js) using app.use().
2. Controller Layer:
- The defined API routes are associated with functions in controller files (e.g., reminderController.js).
- Controllers act as intermediaries, receiving requests and sending responses. They do not contain the main business logic.
- Controller functions call corresponding functions in the service layer to handle the actual data operations.
- Error handling is implemented within the controller using try…catch blocks to manage potential errors during service calls and send appropriate error responses to the client.
3. Service Layer:
- The service layer (e.g., remindersService.js) contains the core business logic for each CRUD operation.
- Service functions receive data from the controller, perform operations (like data validation or sanitization), and interact with the model layer to access the database.
- Services can also interact with other services or external APIs if needed.
- The service layer can throw errors if operations fail, which are then caught by the controller.
- For example, reminderService.getAllReminders() would fetch all reminders by calling the model, reminderService.getReminderById(id) would fetch a specific reminder, reminderService.createReminder(data) would create a new reminder, reminderService.updateReminder(id, data) would update an existing one, and reminderService.deleteReminder(id) would delete a reminder.
4. Model Layer:
- The model layer (e.g., reminderModel.js) is responsible for directly interacting with the PostgreSQL database.
- It contains functions that execute raw SQL queries for each CRUD operation.
- Each function in the model performs a specific database operation:
- reminderModel.getall(): Executes a SELECT * FROM reminders ORDER BY created_at DESC query to retrieve all reminders.
- reminderModel.findById(id): Executes a SELECT * FROM reminders WHERE ID = $1 query to retrieve a reminder by its ID. Placeholders ($1) are used for security against SQL injection, and the actual ID is passed as a parameter.
- reminderModel.create(data): Executes an INSERT INTO reminders (notes, reminder, user_id) VALUES ($1, $2, $3) RETURNING * query to create a new reminder. The data (reminder, notes, user ID) is passed as parameters to the query.
- reminderModel.delete(id): Executes a DELETE FROM reminders WHERE ID = $1 query to delete a reminder by its ID.
- The update operation (reminderModel.update) is built dynamically in the service layer based on the fields to be updated and then executed by the model.
- The model functions use the pg library to connect to the PostgreSQL database and execute the SQL queries.
5. Database Migrations:
- Database tables (like users and reminders) are created and managed using database migrations.
- Migration files contain SQL code to define the table schema (CREATE TABLE) in the up function and to revert these changes (DROP TABLE) in the down function.
- These migrations ensure that the database schema is consistent across different environments and versions of the application.
6. Schema Validation:
- Zod is used for schema validation to ensure that the data received from the client during create and update operations is valid and matches the expected format.
- Schemas are defined for creating (createReminderSchema) and updating (updateReminderSchema) reminders, specifying data types, required fields, and constraints (e.g., string length).
- A middleware (validateData) is created to apply these schemas to the incoming requests before they reach the controller. This middleware uses Zod to parse and validate the request body against the defined schema. If validation fails, an error response is sent back to the client; otherwise, the request proceeds to the controller.
7. Handling Request Data:
- Request parameters (from the URL, e.g., /reminders/:id) are accessed using req.params.
- Data sent in the request body (for POST and PATCH requests) is accessed using req.body. The express.json() middleware is used to parse the request body as JSON.
8. Front-end Interaction (Briefly Mentioned):
- The front-end (React Native Expo) will make API requests to these defined routes using methods like fetch or a library like Tanstack Query.
- Tanstack Query mutations are used on the front-end to perform create, update, and delete operations. These mutations send requests to the back-end API routes and handle the responses. On successful mutations, the front-end cache is invalidated to reflect the changes.
In summary, the implementation of CRUD operations in this tutorial follows a well-structured, layered architecture. API routes are defined to handle client requests, controllers orchestrate the flow, services contain the business logic and interact with the data through models using raw SQL, and database migrations manage the underlying database schema. Input validation ensures data integrity, and error handling provides a robust user experience.
Building a React Native UI with Expo Router
The source discusses building React Native UI as part of creating a full-stack Apple Reminders clone. Here’s a breakdown of the key aspects discussed:
- Core UI Library: The front-end is built using React Native and Expo. React Native is described as the primary tool for the front-end.
- Fundamental React Native Concepts: The tutorial emphasizes the importance of props and state as the “bones” of React Native for managing data. React Hooks, specifically useState and useEffect, are highlighted as essential for functional components.
- Basic UI Components: The tutorial utilizes fundamental React Native components such as:
- View: Used as a container for other components.
- Text: Used to display text.
- TextInput: Allows users to input text.
- Pressable (or TouchableOpacity): Enables components to respond to user touches.
- ActivityIndicator: Displays a loading indicator.
- FlatList: An optimized component for rendering dynamic lists of data.
- SafeAreaView: Ensures content is rendered within the safe area of the device screen, avoiding notches and status bars.
- Layout and Styling:
- Flexbox (flexDirection, alignItems, justifyContent) is used for arranging UI elements.
- Inline styles can be applied directly to components.
- StyleSheet.create from React Native is introduced as a better practice for organizing and reusing styles. This allows for defining styles in a separate object and applying them to components using the style prop.
- Properties like margin, padding, borderWidth, borderColor, fontSize, fontWeight, and color are used for styling.
- alignSelf is used to align individual items within a flex container.
- gap is used to create spacing between items in a flex container.
- width and height (including percentages) are used to control component dimensions.
- Navigation:
- Expo Router is used for screen navigation.
- The main entry point for routes is within the app directory.
- Link component from Expo Router is used for declarative navigation between screens. The href prop specifies the target route.
- Layout files (_layout.tsx) are used to create wrappers around screens, allowing for persistent UI elements like headers.
- Stack from Expo Router provides a stack-based navigation pattern with headers and back functionality. stack.screen within the layout allows configuring options for individual screens, such as hiding the header (headerShown: false) or setting the header title (headerTitle).
- Programmatic navigation is possible using the router object from Expo Router, specifically router.back() to navigate back.
- Modal presentation (presentation: ‘modal’) is available for screens, providing a modal-like transition.
- Displaying Lists of Data:
- The FlatList component is used to efficiently render lists of data.
- It requires a data prop, which is an array of items, and a renderItem prop, which is a function that takes an item and renders the corresponding UI.
- The item prop within renderItem provides access to each individual data object in the list.
- Props can be passed down to custom list item components within the renderItem function.
- keyExtractor can be used to provide unique keys for each item in the list, improving performance [Not explicitly shown in the excerpt, but a common practice with FlatList].
- ListHeaderComponent can be used to render a component at the top of the list.
- showsVerticalScrollIndicator can be set to false to hide the vertical scroll bar.
- Handling User Input:
- The TextInput component is used to capture user input.
- The value prop binds the input’s value to a state variable.
- The onChangeText prop is a function that is called whenever the text in the input changes, allowing you to update the state variable.
- The multiline prop allows for multi-line text input.
- Reusable Components: The tutorial emphasizes creating reusable UI components (referred to as “Lego pieces”) to make the code more modular and maintainable. This involves creating separate component files (e.g., ReminderListItem.tsx) and passing data to them via props.
- Conditional Rendering: UI elements can be rendered conditionally based on certain conditions, such as the completed state of a reminder. This is often done using ternary operators or if statements within the JSX.
- Type Safety with TypeScript: TypeScript is used to ensure type safety in the React Native code. This helps in catching errors early during development. Types are defined for props and state.
The source provides a practical, hands-on approach to building a React Native UI by demonstrating how to use various components, manage layout and styling, implement navigation, display dynamic data in lists, and handle user interactions within the context of a real application.
The Original Text
hello and welcome back everybody uh today’s going to be a fun one because we will be building a full stack Apple reminders clone with React Native Expo Express.js and PostgreSQL so if you’re a beginner looking to take your first steps into full stack development I think you’re in the right place because we’ll start from scratch break things down step by step and by the end you’ll have a working app and the confidence to build even more so grab a coffee get comfy and let’s dive in so as I mentioned we will be working on a full stack Apple reminders clone uh we’ll be working with mainly with React Native Expo PosgreSQL and Express.js and I’ll cover more technologies that we’ll touch uh a little bit later but this is going to be our basic fundamental technologies so let’s dive a bit further and check out how our application will look like so first of all uh it’s not going to be as fancy on the front end because I will try to focus a little bit uh more on the back end and um therefore it’s uh yeah I want the beginners to have their first steps and to feel comfortable to get a good grip of how to structure their back end how to structure their front end how to tie everything together basically to help them either start their career or at least have good fundamentals to find a job the things that are like very needed to know but as a junior developer so let’s continue we’ll be working also on create new reminder screen so here we’ll be able to create those reminders we’ll be able to provide a title and some notes bas basically then we’ll be working also on updating uh or deleting these reminders so yeah if you created like a wrong reminder or you uh just don’t want to have it anymore you’ll be able to delete them modify them and so on so the technologies that we will use mainly will be for the back end uh NodeJS as our JavaScript runtime environment also uh accompanying that we’ll use ExpressJS as our framework which is a very popular combination then for our database we’ll be using Posgra SQL and it’s a relational database it’s a very popular one and I think most of the corporations use that so it’s going to be very good to know how to use it how to write uh SQL queries and I’ll touch a little bit more upon it later and also we’ll use ZOD for schema validation if you use uh any other technology for this you can totally do that i just feel that this is something I’m mostly comfortable with and that’s why I will use this and it’s a very popular one as well so it’s not bad to know it then for our front end we’ll be using React Native and Expo and I think that’s not a surprise to anybody because on this channel this is mainly what we use so yeah that’s nothing new here then we will be using expert router for our screen navigation we’ll see how to use it and how to implement then we’ll be using TypeScript to ensure type safety i’ll basically cover all the basics of it uh so you could understand how to write types how to why is it good and why you would need that it’s going to be very good to know and lastly we’ll use tanstack query for data fetching and caching our data so yeah this is our tanstack so let’s quickly recap and basically understand what are you going to learn in this live stream mainly we’ll be working uh and creating a a REST API with ExpressJS u so this is a very general topic but I’ll dive a little bit deeper uh what we will learn now so yes we’ll cover database database management using Postgress SQL for the data persistence how to store it how to retrieve data and much more then we’ll be working on schema validation to know that basically the inputs that we are receiving from the user are they correct and automate this a little bit better um then we’ll be learning how to handle the errors and the best practices to handle these errors correctly uh because there’s a lot of different ways and uh you can structure it differently so this is also quite important to know uh then again we’ll cover on the project structuring and how to structure it and organize for a let’s say easily maintainable uh application so this is also going to be very good to know for beginners because a lot of big corporations uh will be using this kind of structure it’s a very popular structure and knowing this will help you let’s say understand everything a lot faster of course we need to learn how to do the main CRUD operations uh so creating new records reading them updating them and deleting them from the database and also we’ll learn database migrations so how to manage them how to create them how to run them write them and stuff like that uh so for the front end now let’s see what we will cover here as well so as always props and state that’s very important to know that’s basically bones of uh React Native and managing the data so we’ll cover that we’ll be covering the flat list and how to create dynamic lists then we’ll check how to work with navigation how to navigate between screens and um yes like that then as mentioned TypeScript uh React hooks which is very essential uh to know especially the use state and use effect and we’ll see how they work they’re let’s say one of the more popular ones then we’ll learn how to make the API request request to our back end that we will create from the front end our application and that’s it so now let’s cover a little bit why I think the project based learning is the best way to learn and uh well first of all building uh you build the realw world apps you build them you don’t uh study too much theory but you understand the theory along the way you see how everything ties together and it’s very important this is actually how I learned and how I was taking my first steps and I would recommend that to every everybody then again you are getting as mentioned hands-on experience instead of just theory so it’s very interesting to see how everything ties together and um yeah witnessing that by writing your your own code and then again at the end you will walk away with a functional app that you can uh show to whoever you want and say yeah this is what I’ve built so let me quickly also talk about myself and uh who am I so I am a software developer i have quite a few years experience in this field and I am already only like let’s say six plus years u startup CTO and co-owner um then I was also former and university instructor in software engineering and we did that together with Vadim so shout out to him as well and I believe uh I always like to say I’m a developer first and educator second because I learned everything uh by heart i tried I failed and now I think it’s time I developed a lot of things and now I think it’s time to share my knowledge and maybe sometimes you see there is issues where you forget your microphone but that’s why I’m only learning to educate and share my knowledge the best way I can so that’s a little bit about me i think we can get started and uh start getting our hands dirty as they say so let I will meet you in a second but we are still here so but before we go and do uh anything else I just really want to um tell you about this course that Vadim was working tirelessly on for a very very long time and we’re finally done with it we are editing the last few lessons and we’ll be publishing it but you can already check it out you can already enroll to it it has everything that you need to know about React Native completely everything in very very much detail with the huge guides and videos so if you are considering if you are looking for a well ststructured course in React Native I highly suggest you to check it out and uh you will definitely not regret it vadim is actually currently even working to adding uh after each lesson each workshop that you learn uh educational exercises so it’s going to have even more value so guys check that out and I’ll be using a step-by-step guide in this tutorial that you can download by going to this to this link or going to the description of this live stream and finding and clicking on a link uh very similar actually the same link it’s going to be near the title saying uh get your asset bundle and step-by-step guide and um after clicking on this link you’ll need to provide your name and an email and we’ll send this guide that I will show you in a second uh to your email address so then you can reuse it anytime you want any changes I will do in the future you can get on that guide and check it out usually after the streams I try to improve the documentation if I see that people are having issues with certain uh topics I try to add more and u yeah make it even better so check it out if you need it but if you don’t need it it’s okay not to download it but yeah so let me show you this guide that I was talking about and uh we can close this off so yeah this is the guide uh in here I have like a short introduction of what we will try to learn of the text tag that we will use and a little bit more of the information but the main meat let’s say quote unquote is in this um let me reload it is in this part here you can see basically the lessons that will be covering everything and if you click on one of these lessons you can find even more information about it And um yeah probably I will not cover in the this live stream some of the very small things that I write here as let’s say uh little uh call outs i’m not sure how to tell uh tell what they are but here also you’ll have let’s say some comparisons uh more information how to do it step-by-step guides so I’ll be using this myself along this tutorial but if you let’s say do it later on make sure to go to the description download it and you can follow it along as well together with me but our first step is going to be setting up uh well actually before getting into the meat let’s see the comment section because that can be wild yes I see a lot of different comments and um yeah that’s a lot of comments about the volume but that’s already fixed I think and let me know if it’s not too low the volume if it’s let’s say good enough uh okay mhm lucas is here amazing tutorial the walking engineer thank you thank you very much uh nice to see you here as well go Lucas Mario yeah thank you thank you catalin thank you uh can we build large scale applications using expo 150% uh I’ve done it and I’ve used it actually I am using it in my startup there’s a lot of huge applications that use uh expo and actually this is the best way to build react native applications in general and in my opinion to build applications uh uh so yeah it’s a very good um very good tool framework to use uh is 10 stack query only for front end yes now will be yes the idea of the application is so good luck Lucas uh thank you very much uh coders loi station what about style guides and test cases sir so we’ll be uh we won’t be covering test cases uh here today but again keep on suggesting uh things that you want to see in the future we can definitely expand upon this tutorial a lot more because now as I mentioned I’ll be covering like your first first first step if you want to let’s say build your own back end build your own front end so it’s going to be very low level only the most important technologies um I didn’t use over-the-top let’s say technologies so that basically I’m trying to help you uh get a job let’s say or uh build your own application and then later on we can expand on even more things with time so keep on suggesting that um can you provide the link i imagine um I’m not sure if it’s a link to the React Native Mastery or to uh I I would assume so maybe if someone is watching from the team could you uh paste a link of React Native Mastery but I believe you can also find it in the description below so yeah check it out uh can I follow this tutorial with an Android phone yes you can totally do that um it will work just the just as we will do on iOS it will look a little bit different but the the differences will be like minimal so you can definitely do that hello from Turkey hello from Lithuania hello can we get a link to this notion site okay so maybe about this notion um you can uh get a link I think I can try to copy it as well so give me a second but you can also get this this link in the description of this video um but let me actually um okay okay okay let me go here and I will try to download it i mean try to copy it and then send it to you guys okay it’s here so tell me guys how are you doing how are how is your week are you ready for the weekend or what are you going to do during the weekend do you have any plans or is it okay and of course the ads uh no um no link in the description okay that’s interesting but here it is so yeah here in this link you if you open it you will uh be redirected to our site there you need to provide your name and an email and we will send you in the email the link basically to this notion site so feel free to check it out okay think we are ready so let’s start working on it so yeah if you open this guide go to the first lesson um not coding question is the cold cucumber soup from Poland and Lithuania um I don’t know about cucumber soup we have the cold um it’s not a cucumber how is it in English like borch but uh I’m not sure how that that plant is called in English uh but it’s like a violet kind ofish but the cucumber su probably it’s from Poland i’m not sure but yeah let’s continue with that uh yes so if we go to our guide click on the first lesson set up a fresh NodeJS project and let’s see what we need to do here well first things first yes beetroot that’s our soup that leak didn’t work how is it not working it is working for me you provide the name and email and download it um yeah I’ll try to double check it with my team uh but um it should be working can okay yeah I’ll let you know in a second uh of what’s happening there oh it worked perfect then so yeah let’s now get into the meat uh so before we begin it’s very important to ensure that basically we have NodeJS installed on our machine so as I mentioned already in the presentation NodeJS is a JavaScript runtime that allows ows us to execute basically JavaScript outside of the browser so to check if you have it installed already open your ter terminal and simply write node slashv dashv probably and you should see your basically version of the node if you see some sort of an error or anything else except for this version it means you need to install it and in order to install it just go to their official uh website that I provided here and download the LTS version basically if you install it you can it’s very easy to do that and then we can continue together yeah so now because we see that we have already our node installed we can create um basically we can paste this um commands in the terminal and by by doing so we will create a new directory called Apple reminders API so first of all let me navigate to the page where I want to create it it’s going to be um yeah project documents projects and in here I will paste uh the command so first of all let’s do it one by one first of all I will create a new directory with the name of Apple reminders API so enter now if I do cd which means basically to go we can copy the name of that the directory that we just created and we will go to this directory now we are in here perfect so let’s see what we need to do next well we need to initialize our MPM to do that it’s very easy just run npm in it and that’s it so let’s copy that run it and um yeah and that’s it we are basically inside the initialization so we need to provide a few let’s say inputs here if you want you can leave them completely by default and just click enter for me this is the good name so I will click enter the version is going to be 1.0.0 so again I’m going to click enter the description it’s not it’s optional so we will not provide it enter and the entry point for us it’s going to be index.js so it’s also I’m just going to click uh enter and the test commands as I mentioned we will not be covering tests today maybe we can do it some in the other tutorials if that’s something you’re interested in but I’ll just click uh enter as well and the git repository well I highly suggest you to work with it but uh I will do it later on keywords no keywords and author well we can give author as Lucas license IC and this is basically a quick overview of what we just went through so is it okay uh yes i’m just clicking enter and that’s it we’ve initialized it so now we can go uh to our uh where is it let me maybe rearrange a little bit like this go to VS Code if uh if you don’t have VS Code it’s um very easy to install it just um yeah you can go to your browser go to VS Code download VS Code and you will install it but if you’re using any other code editor that’s completely fine and it’s going to work just the same so now that we installed it we need to uh run mpm install express well first of all we need to open the terminal so actually not the terminal but we need to open the project that we just created so let’s click open and let’s go to our uh it’s in here in project and Apple reminders API so now if you navigate here let’s click open and we are inside our project you might get this little popup so just don’t worry click yet click yes I trust authors and that’s it we can close this welcome we can open it here and we can see yes this is exactly what we’ve provided while creating uh while providing basically those inputs so now it’s time to actually open the terminal so let’s go terminal new terminal and in here we will paste this command to install the express framework so let’s copy it paste it install it and u yeah yeah yeah it will install it very quickly and you will see that it created this package uh.lo and node modules right away and you can also see that inside our dependencies basically our project dependencies we have already express with a version of 5.1.0 zero perfect that’s very good so we can continue further now we will be enabling uh the EA6 uh modules which is in my opinion very neat it’s going to make the code a bit more readable and uh let’s say more modern uh so to do that we simply need to pass the type module in our package.json actually the only thing it will change is instead of doing uh the const uh dot basically require we will do import and then we will say what we’re importing that’s a little bit of a modern more modern way of doing that so let’s go here let’s add the type of module and continue further so now we will be creating our first entry file with a very basic basically application so you can simply copy all of this code because yeah I’m for now I’m copying the code but later on I’ll be writing myself uh but yes I will copy this one just because it’s a basic template and you will have it also in express uh documentation so we copy that code but before doing anything else what I always do uh is I create one folder called source in this folder we will keep basically all of our source um code basically all of the code that we will create now and um yeah this makes it more readable and um that’s a very good practice so inside the source we need to create our um entry file which is going to be index.js so if we create that we can paste the code that we just copied in this index uh file so let’s quickly go over what this is doing well first of all we’re importing the express that we the dependency that we just installed then we are creating the express application instance and later on we will be using it here we are simply specifying on which port we want to run our server uh so yeah you don’t need to have have it in a variable you can just pass it as a yeah like as 3000 but later on I’ll show you even a better way of having it and then we have one request already created basically to the um URL slash and this URL will basically that’s kind of a route that we’re defining and inside here we are saying okay what this route will do so when the user goes to this uh URL what’s going to happen well for now we are simply going to return hello world later on we’ll expand it and lastly we are saying here listen to the port that we define here so this in this case it’s 3000 or you can have like 3001 or yeah any other port uh that you feel is better and then um we are console logging that okay example app is listening on this port so once you have this all of this code click command S or control S if you’re on Windows to save this and now we need to run our server so if you go here uh what we will need to do is once again open the terminal you can either open it like this or with the if you didn’t close it you can run it right away here so what we will say is that we want to run our server and it from the entry point of source so going in here and index okay let’s click enter and right away we see that example app is listening on port 3000 that’s amazing so if you’re following the um if you’re following my guide that I created you can open just click on this uh link and you it will open you basically a localhost uh website or you can simply write yourself here localhost 3000 click enter and you will see hello world response so now if we go here and change hello uh not just developers if we save it then we need to restart actually we need to uh yeah restart it uh yes let’s go here loc local localhost 3000 and it changed to local hello not just developers so yeah like this is specifying the route the link that we’re going but if we would say here uh slash and not just let’s say if we go back here if we try to reload this actually yes let me for now I will show you later how to solve this and we will not need to restart it manually every time but so bear with me this would be insane but for now we do need to do that so if we go here if I’m going just to slash it says I cannot get because we don’t have any route that’s only like slash slash we have a route however with slashnotest so let’s try if it actually works like that if we say slash not justest and click enter we’re seeing that okay it works but we can specify many routes we can say uh okay so then let’s have also a route that’s only going to be slash and if we again we need to reload our server and go back here so now if we go only to slash it’s going to work to and redirect us return us a response of hello world the same is for the not just it’s still working so basically both of these routes are working well perfect let’s see what we can do to further to make it even better make the initial setup even cleaner well I will introduce you to the environment variables this is a very important file in your application your server back end because hard-coding configuration values like port numbers is quite bad and especially uh hard coding and inside not in the environment file but uh adding let’s say somewhere here inside the application your API keys is horribly bad because it’s very insecure are instead we use environment variables for that basically uh env file so you will have um you will have this file only for yourself you will not if you even if you’re using git you will not push it to let’s say um to your git uh github gitlab whatever you use even if you have this file here uh you will need to create let’s say once you like um host everything to the cloud you will need to upload it there as well separately so yes because it’s very insecure to share these or paste hardcode these uh API keys these values inside your application anywhere so let’s just do that first of all let’s create a new environment file so to do that just in the root root uh directory click anywhere and say new file now in inside here we will say okay we’re creating dot environment file and for now we will have only the port as u as our one environment later on we will add also our de database key which is a very sensitive information and that’s why we will have mainly this environment file 4 okay but now that we added this port how can we use it somewhere in our application well to do that it’s actually pretty simple you do it and here I have an example um but yeah I will guide you through here but we are simply saying that we are taking it from proc process we’re taking it from environment and we need to then specify the environment variable name so in this case we provided the name of port so let’s copy this name and say port okay now we can save it and now this port will be taken from this environment variable which is basically what we provide after equals but let’s give it in in in case there is some kind of misunderstanding and this port is not available let’s do it and I say it here as well let’s have it uh an or statement and basically fall back to a port number 3000 so basically now we’re saying take this port value from the environment variable but if it doesn’t exist simply use 3000 okay so now you might be thinking that it should work but if I try to reload it’s still saying that we are starting on port 3000 even though we provided it well yes because our uh server doesn’t know that we already created and what kind where is this environment file uh how is it called so in order to use that we will need to uh specify in the command that we are using the environment file environment file and we called it uh env so basically we’re giving this this exact name and we’re saying that okay so this file is going to be our environment file so use that where whenever wherever we use process environment okay so now you remember I said about like always needing to stop and restart stop and restart our application well it would be insane if we had to do that after every little change so we can pass another flag called watch and what this does it basically says to the server watch for every change and whenever you I make a change here and save it reload the server automatically so that I don’t need to do it myself okay and lastly we need to say okay so now our path is in um basically entry point is in source.index so now that we have this whole command if we run it we can see that the port the app is listening on port 3001 that means our environment variables are active the uh the server is able to read them and now if I say let’s say I remove this and save it you can see that it’s restarting also automatically our server so we no longer need to do that manually anymore well that’s amazing but remembering this long name every time to write would be also a little bit annoying so we can create a short script and it’s a very common u way of doing it if we go to basically copy this one uh yes copy this one and if I go uh to let’s say package uh JSON under scripts we can create our own scripts so basically we will say okay well the script name will be dev and I will show you what the this name is and once I call this we need to call this whole long function so let’s save it and now if I in the terminal if I run to run our server the only thing I need to do is say npm run and then specify the name of this script so you will have quite a few scripts here like for testing and you can even have for various different things but for us the most important one is right now dev so if I say npm rundev and click enter we see that it’s running this long command and we’re listening on the port 301 amazing now the last thing that is quite important to know is also that um as I mentioned committing uh to the version control to the git the environment file would basically make this environment file useless in a way because it’s very insecure to commit such a um valuable let’s say or crucial information later that we add like our database password because is if someone gets that database password they can connect and basically remove all of our information and that’s quite bad if you probably you understand that so let’s create another file called git ignore and most likely once like when when you are working in a corporation or you have a job you will be using some sort of versioning control like either github or gitlab and they will have this git file so what in this file we specify which uh files or folders from our um from our application we do not want to push to versioning control and usually these are the files that we can configure easily ourselves or very let’s say uh private files like environment so one example would be node modules uh node modules this uh increase the font size okay I’ll try doing this way and I I’m seeing some of the comments guys i will check it out very soon after like every lesson i will try to get to your comments check it out and then we can continue right now I want to like keep it a little bit uh yeah of a flow so now yeah we specify that node modules we do not want to uh commit that because it contains well uh all of our dependencies installed it’s a very huge folder and also I can configure this folder very easily by running npm install and that’s it basically it will look inside our package uh JSON and based on the package.json it will regenerate the node modules so if I can regenerate them that easily I don’t really want them to commit them and also a very important one is the environment file and it’s because we don’t want to commit that because of what I just um talked about basically it prevents us from accidentally exposing very sensitive information so we are almost done at this like first configuration lesson it’s probably the most boring part but it’s very important to know how to configure it properly so that we could get uh get to working so now let’s close all of those uh files and I will um introduce you basically to a tool to test our API calls so of course we know that before deploying our API we want to verify that every route that we define here works perfectly like they they do what they need to do they return what we need to return and yes like that so there’s many different API to testing tools like one of the most important ones is probably a postman uh now in the recent times it’s getting like they have a lot of functionalities it’s kind of over complicated ated at this point uh to start with but you might see it quite often also insomnia is very popular one but it has a little bit in my opinion a better feel for me at least so I will be using Insomnia but feel free to use any other tool it they all work mostly the same they all do the same thing there’s one called Bruno which is also very popular now like more of a let’s say um I’m not sure like indie kind of for indie developers in a way like hipster that’s what that’s the the word I was looking for uh but it’s also very cool so Bruno is amazing okay so let’s download and install Insomnia from their official website which is insomnia rest so once you install that um I have well I already have my account but uh you will see in the main dashboard uh something like this saying that here’s are here are the organizations you own and uh you simply of course first of all install it in your computer you simply need to press open and what this will do it will open insomnia for you and you will see actually exactly the like what you see now here so what we need to do now well first of all I I want to create a new project uh because I want to create it locally and I don’t want to always sync it with my cloud if you’re working with a team you will most likely always choose like the cloud sync and for that you already have one project created but I only want I want to store everything locally for for this project um yeah so it doesn’t really matter too much for you um if you’re working in a company uh they will say which one to use if they are using their own they will probably import in your computer so yeah let’s call it something like personal uh local project and click create or continue then the name now in here let’s click on new collection and let’s call our collection so we will call it reminders API and let’s click create now you will see something like this basically a blank space with u not much so yeah here I have all of the things you need to know and now we’re here uh the creating your first API request it’s actually kind of easy to do you simply click here on a little plus sign you say let’s create a new HTTP request uh you can even like give it a name if you want so we can rename it and say uh get hello world something like this and um now what we need to do is you need this localhost URL here so let’s remove this and copy this local host URL actually now if you run this it’s not going to work because we are running no longer on 3000 port but it’s 3001 and I think I didn’t yes I did not run my application so let’s do mpm rundev so if we go here maybe I should increase size here as well so now if I go um if I go to this local host and on port 3001 we’ll see our old um project so now let’s copy this URL from here and go to back to insomnia in here at the top let’s paste this URL and you don’t need to add this slash because by default it is added if there’s nothing after it but I will add it just for demonstration purposes so now that we have this we see that the request is get and we know what request to use because here we say it’s get so if we go here and send this request we will get exactly the same response and let me maybe also increase it hello world but if we say here not just get we are getting hello not just developers response so it’s um yeah it is how it’s uh what we wanted to achieve in our first let’s say uh first lesson so now let’s go to the taskboard we will take a short break and let’s go to the database uh lesson now I think we can uh check out some of the comments and um yeah there’s a lot of them so probably I’m not going to be able to respond to all of them but yeah um um uh hi will you implement authentication and CSRF token handling no and in this tutorial we will not do that however I’m thinking to do like a separate tutorial for authentication only because that’s kind of like a a broad topic so I didn’t wanted to cramp everything in one uh project one tutorial because you see how deep am I going in some of the things here and I’m even explaining like the very very big like let’s say simp the simplest things quite um detail so having authentication would have been quite an overkill um okay um this is amazing regelio thank you thank you very much uh nice to see you as always in the streams that’s amazing yeah we’ll use Lucia no as I said yeah no authentication um um why not use nodebond package to run the ser uh to run the server automatically i feel this is uh like a lot easier way of doing it it’s uh everything built in you don’t need anything extra it’s very simple and very effective at this point uh do you implement MVC or just simply yes we will work on the full MVC model and that’s one of the um lessons in here we will use MVC plus service layer so basically the way how probably the biggest corporations are handling uh the ones that are using like uh let’s say express framework or even more like uh structure so we’ll cover all of that uh soon soon so yeah I think um more or less uh answered a few we’ll have a short like again burst of implementations and then we’ll come back to to to to some of the comments okay so now database um well probably kind of you know if you don’t why we need a database is basically to store and manage our data we need to somehow persist that data and uh when the user let’s say creates a new reminder we need to store it so that later when he opens his application we can actually retrieve that data and show it to him so there is a lot of different types of databases and uh for this project right away I’m saying like we will use a serverless database uh posgrade SQL as well and we’re using posgrade SQL because it’s probably the most popular I would say and it’s very good so yeah that’s that but let’s really uh quickly cover all of the t like not all but main types that you might encounter of databases so first one is self-hosted database either on your virtual machine or even on your own servers that you own this is basically where you install configure and maintain the database on your own um you have a full control yes it can be optimized like for very specific use cases but it requires insane amount of database management expertise and knowledge usually you would have your own database management team only for that so it wouldn’t it’s kind of complicated because you need to handle the backups the scaling uh everything everything yourself you need to set up and u it’s very complex so it’s not going to we are not going to be using that and if you’re working on creating your own application you’re also definitely not going to use that bigger corporations with the huge teams huge let’s say budgets may be using this uh so you might encounter this but for you nothing will change from what I will show in this tutorial then there are managed databases something like RDDS uh Google also has one um and uh basically it’s a cloud provider that manages your databases it manages the backups the scaling and all the maintenance so you kind of don’t need the full team to ma maintain it it has like automated backups and um this is probably the best suited I would say uh if you can’t really afford this for constant high traffic applications but it can be very expensive if you do not optimize it properly so basically if you leave default options this can get crazy expensive and if you don’t really know what you’re doing so you are required to fine-tune uh for the cost and performance quite well so you still need to know what you’re doing and there are uh serverless databases uh like the one that we will use today Neon there’s a lot of them there so use whichever you want i just felt this is the easiest one to use so that’s why I chose for the tutorial and it’s a good one actually also not that because it’s only easy but yeah it’s like fully cloud managed it al auto automatically scales based on the demand and we pay only for what we use so we don’t need to manage any servers it’s kind of costefficient because um for unpredictable workloads because you kind of don’t know maybe sometimes the traffic is low sometimes it’s very high so it balances out in a way it’s very easy to deploy and we’ll see how to do that and start using it however it also has some cons like uh you have less control over tuning and optimizing it potentially there might be it might be more expensive if your application is consistently having like a very high traffic but um it’s still it still can be good so it’s very difficult to say which one will be the cheapest it depends a lot on your um on your uh like use case but uh serverless if you’re working like on a startup is more more times than not will be the way to go so again why serverless well for us it’s the best choice because it’s easy to set up start using it eliminates any maintenance task it scales automatically and it has an amazing free tier so basically you can use it for free even after even uh publishing your app to production it’s still good for free for quite a bit of uh data and time only when you reach a certain threshold uh threshold you will need to go into the paid tiers again however if you’re using consist consistently high traffic applications you kind of can think about as RDS so now let’s see how to set up our database well first of all let’s just go to Neon’s official website which is um neon.te in there create a new account and after creating this new account you will see a this screen like exactly this screen maybe you will need to click click new project as well but I think it automatically opens this screen and here we need to provide the project name for our database uh so let’s say it will be reminders API uh I think I have the same so maybe Apple reminders API um database name you can provide it or you can just leave uh Neon DB we can say reminders uh database um and then you can select a region so in in theory you would select a region closest to your main target audience the people that will use your application for me I will use the one that’s closest to me uh so yeah it’s either central or west let’s say Frankfurt and then we click create now that we are in this uh okay I see there’s some a lot of questions um uh um uh hello Lucas could you please show us how to install a React Native Expo application on iPhone without going through App Store for example if you have an app you want to install among friends you mean basically not to publish your uh application to the app store so that only you and your friends could test it out and use it let me know if that’s uh that’s that real developers use Microsoft Access for database concern dodge okay uh where do you get your app designs do you do it uh or do you outsource it so it really depends uh so if you’re a small team usually you can do it yourself um for for a developer it’s good to know the basic styling but if you are let’s say in a big team big corporation more times than not they will have their own like UI UX team that will handle these things so you will only need to know how to apply these tiles but uh yeah like in a startup you would need to do it more times than not yourself unless you have a lot of investments okay let’s continue uh so now that we logged in we provided everything selected the region we will need to connect our database but before that I really quickly want to talk also about using raw SQL or OM and what is it a difference between them so um uh at a very high level an OM is a tool that uh allows us to interact with a database using object-oriented code instead of writing like raw SQL queries queries um this which makes the database operations easier to read and write so here you can see an quick example so here is how it would look in a raw SQL so you need to remember like the structure and everything it might be for some people very unintuitive and for example a drizzle or has something like this which makes it for maybe even easier to read and well again RMS have additional benefits on top of that but we are focusing on a key difference between these two and uh yeah it’s again also worth noting that many ORMs allow developers to write SQL queries when needed and it’s very it’s kind of common for well it’s not uncommon maybe that would be the better way of putting it for companies to use a mix of both like OMS for simple operations and raw SQL for performance ments but today we will be using raw SQLs because well this is a learning project and I believe and I I would argue like very harshly that it is a lot better to understand SQL and it’s a lot more valuable to learn that uh than simply relying on an RM so by working with directly with these SQL raw queries you’ll gain a very good foundation uh of database interactions and you will definitely I’ve never heard of someone trying to apply to the job and uh the uh job is saying no sorry we cannot take you in because you don’t know the ORM that we are using but not knowing an SQL queries might be a reason you are not accepted so it’s kind of important to know it it depends on your position but it is important and here you can see also like a quick uh comparison between using like uh an RM and Ross SQL why is better so main probably difference between is the performance one and the Rossql often is faster because there’s no overhead or no like abstraction I meant and um yeah but here you can read a little bit more about it and let’s I see music forever is asking why we not use superbass and you could definitely use superbass here I just thought like uh neon fits better In our case it’s only like a posgress database it’s a simple thing it’s very simple to deploy it and use it if you want you can use superbase um it’s just as good uh but here yeah I chose neon so connecting to our database yes let’s continue so in order to uh like write these uh SQL queries we need a library for that and we will use um install pg uh I mean pg which basically stands for posgress and this is the most commonly library it’s called node posgress which allows us to execute these queries and it also allow like supports uh connection pooling which is very good for performance and you can easily adapt it to any other services it’s yeah very very popular one so to install that just let’s copy this command and go back to our code let’s stop this server with Ctrl C and let’s paste this command install pg after installing it you can see that it appeared here so perfect now we need to connect to our database finally so if you go to your database uh dashboard and click here on connect you will get this uh connection string copy it in here by clicking copy snippet and go to your project for me I will um it’s not a problem to share this password because I will remove this database uh right away and I don’t I have like limits set but for you I would um be very careful by sharing this password so once we’re here let’s create some more folders to keep the structure very good let’s say in the our application so let’s click on the source and click create new folder and here we’ll create config this is where we will keep all of our configurations in this case we will have only one basically configuring our database but you might uh encounter more things in let’s say very big projects uh but what you will see definitely there is going to be db.js so in here what we need to do is um create this connection between our server and our database to do that let’s go to the environment file that I uh introduced earlier to you today and we will need to add this connection like this so we will say uh we are creating a new uh environment variable called database URL I think yes and then I will use this URL pasteed basically this connection string from here so now that we have this URL we can go uh and create this connection between um our server and the database this is the code for that uh I will copy it because there’s nothing crazy here and I will go over of what we’re doing so go to this DB and paste this code if you do not if you did not download the notion guide just pause the video and um you can write everything out but basically what we’re doing is we’re importing the pg the library that we just installed we are creating this connection pool that I talked about by simply passing the connection string from the database URL that we defined in here then in we will remove this uh function very soon but we have this function just to test if our connection is working properly so basically what are we doing here we’re connecting to this pool basically and we’re trying to query the version of our database right now and simply console log the version if it does this if it connects and uh returns me uh basically successful query that means everything is working and we can finally uh release the client otherwise uh something is not correct if it won’t return us the version so let’s see what it will return and here we’re just simply saying at the end of this file just call this function so the run this function call this function so let’s open uh our of course let’s save it and then let’s open this um terminal once again you can do terminal and new terminal or create or use a shortcut in here we will say run the script uh run the node is going to be in source uh in config and in db once we click enter uh we can oh yes it’s not going to work because we’re trying to access here the environment variables but we’re not providing okay so which where are those environments stored so we need to provide environment file env yeah here I’m talking a bit more what we’re doing here but what we can see is we have the correct response which means everything is working perfectly so now we are done with yet another lesson and we are kind of uh already 1 hour in but it’s okay I want to make it detailed so let’s go to migrations as our next lesson uh let’s open it up and we can now once again take a short break see what’s happening take a sip of water because I didn’t do that for a very long time already okay no new comments um it’s good it’s good so I think we can continue u if you have questions just let me know if you have any feedback always uh let me know as well and let’s yeah let’s do some more coding so now that we are here I hope I’m showing yes we will learn a little bit more about database migrations and here I have a huge block of text uh telling you what are they but in a way migrations are changes to a database schema that are version controlled this is very important and um we create them in order to apply these migrations and the I mean these changes in a very structured way this allows us to have basically maintain a very consistent u database schemas across different let’s say environments and typically companies will use different tools for this so there is a very popular one connects SQLize uh this is already like or even Prisma i saw someone is uh asked why I’m not using uh Prisma and um yes it’s because I really wanted to keep this whole thing very very low level and cover in much detail the things because not every company that you will apply to uh for a job will use Prisma there’s a lot of different tools that you can use instead of it and uh I just wanted to give you like a low-level knowledge of how to like create everything and work with everything and do not attach you to any of the tools that uh the company that you’re applying to is working like with different tools or with the same so yeah Drizzle is also uh a very popular one it um it also like an as an OM i gave an example with it previously so yeah but I just wanted to keep it very very low level as mentioned but so yeah these tools um help you a lot uh but we will simulate how it’s going to look like uh very very similarly so let’s first of all uh you will always have this migrations folder so let’s go to our project let’s close the config of the folder and let’s create another one inside the source called migrations inside this migrations folder you would usually use a tool to create this migration so yeah like there is it would be something to like migrate or whatever and um uh and then you would say like the the migration name that you want to apply and it will create a file similar to this first of all it will have a timestamp so let’s create today’s time stamp and it has um and then it will have a name of the basically migration that you are creating so for us it would be let’s say something I actually have some names here so yeah create user table so let’s rename it let’s create this migration called create user table and it’s more times than not uh will use this syntax also so yeah you’ll feel right at home when you see it it’s just you’re not going to create them manually so now that you created these let’s say migrations files um yeah like I’m telling here a little bit more about the naming pattern and it always will include the time stamp so how to write these migrations well here we have a little bit of an example once again um should I write it or just copy this is like a very yeah there’s a lot of setup let me copy and just go over but maybe I will like start writing them uh now let me know like should I do this setup uh setup code like in a writing everything step by step or just for now copy paste and then later on just get into the meat so for now I will paste it but yeah let me know okay so what are we doing here well first of all we’re importing the database um from this config file which is config db so in here we can see that we’re going to two like we’re going one folder back then we’re going inside config and we are uh going inside the DB um okay people are saying step by step so let me create this one like explained like this and then the reminders one we will write step by step then and from now on everything will be written step by step so here we are creating two different functions one is going to be down called down and the other one is going to be called up and this usually means we are migrating up and or we are migrating down so migrating up is usually you create some something new but if something didn’t work you create the migration down to revert the those changes back so what it means so in the up we are what we’re trying to do is creating a new table in our database so what we’re doing here we’re saying okay create table basically create a new table if it doesn’t exist yet because if it will exist it will not create and the name of the table the is called users okay now we need to specify what this table will have well first of all and almost all of the tables will have the ID which is going to be a serial uh primary key what what means it’s going to be like a primary key And uh it’s going to be auto incremented with every new record that you add so basically none of them will have the same ID all of the records different ID then it will have a name uh for the user this name can have like up to 100 characters uh and it should be unique and it can never be null so it’s a required field we need to have the user name and lastly we will have a created out uh which is going to be a timestamp and if it’s not provided once you create an every like new record new user we will default this timestamp to the current time stamp basically it will take the current time and add it as a created at and that’s it like we are running this query and if it doesn’t work we will catch it and throw an error now like how to revert this migration so if we saw that okay we migrated up but it’s something that we shouldn’t have done how to revert it back well we have for this this down function and what it does it’s simply dropping the table if it exists and the table name is users so the same as we created so yeah if we created it if we don’t need it anymore we call it down and then at the end here we will call a function so it’s either down or it’s either up usually again if you use a tool it might be something that you would simply call uh migrate up uh or migrate down or something like this it depends on the tool you’re using but for us we are going to specify it like this but like this part will look the same and you you will feel at home you will know what it’s doing so now in order to run this migration what we need to do is we need to say uh go like once again node we need to specify the environment file and it’s going to be so you could actually even create scripts for all of these if you wanted to so we are saying use environment file uh env source then we’ll go to migrations and then we will call create users table migration so now if we click enter uh we yes we are still calling this but we can go back to our it created it but we can go to our config db and remove or comment out this part because we will no longer need it we test it it works it’s good so I will remove it you can console it i mean comment it out and later uh we will you you can reuse it if you wanted to so now if we go to our neon console if I reload it um and go to tables under tables we can see a new table called users perfect with an ID as a serial with a name as we uh maybe I can make it bigger here yes with an ID as a serial uh with a name as a basically varch of up to 100 characters and created at time stamp so for example we can even create a record just in here right away and we can see that these two values have a default value but this one we do need to provide it so let’s say I will say simply Lucas and save it and it created a new record with a created at time step of actually right now but in in a different um time zone and with an ID of one well perfect so now we need to do the same for reminders and now we can try to write this uh reminders code or like migration ourselves so first of all what are we doing we’re importing the database from and we will say okay so let’s import it from config and database and adds very important unless it’s got otherwise it’s going to throw an error for you okay now that we imported we have two functions well one of them is called uh up so we will say export a synchronous it’s very important function and the name of the function is going to be up parameters it will not have any and Now we can inside it define the try catch uh so select this one the try catch right away try catch um I forgot the the word but basically yeah try catch in order to try to execute some code and if anything inside this block fails you will uh execute this so here we are again uh defining the query so we are saying await db and we’re saying query so from this DB we’re’ll execute the query and the query will be as follows so let’s adjust a little bit like this and let’s try start defining well first of all if you remember we will create uh table if it’s also very important to say if it doesn’t exist yet if not exists and now we give the name of the table which is going to be in our case reminders now we can start specifying okay what what fields will it have well first of first of all it will have ID which is once again going to be the same serial and also it needs to be a primary key i hope I’m not going to make mistakes in writing uh typos but we’ll see it because it will catch the error and console log it for us then we will add another um field uh called like reminder so we need to actually uh the actual reminder that user will save so it’s going to be again varchar and we will give it let’s say 255 characters then it also cannot be null that’s the only um like basically the most important part of our this reminders records like it’s the reminder itself that the users will save then we will have another one called notes and this can be uh empty it’s very like optional so simply a text will suffice then we will need to know if the user actually completed completed the reminder or not yet so it’s going to be a boolean basically either a true or false and if it’s not provided when we are creating we will default to false so basically because we kind of know that if the user creates a new reminder by default he’s not going to be done with it it’s a new one that means it’s still not finished then we will also need to know to which user this reminder belongs so the user will be an integer and we will reference so we say references and we need to now say the table name so if we remember here we created users table so we say it references user and it references the ID field of the user so basically this we are creating like a relationship between this user uh between this reminder and the user and also we need to say like if this user decides to remove his account so with it we need to remove all of his reminders as well because we no longer need them so we will say on user delete we will cascade and cascade means basically remove uh all of his reminders and lastly we also need created at time stamp and it’s going to be exactly the same as for the users table it’s going to be a timestamp which will default to current uh timestamp i hope I didn’t make any mistakes but if I did we’ll see as as I told already and then we will if there’s an error we will console log the error itself perfect let’s maybe add this as well here so now we need to create again another function to migrate down so let’s say uh not expo export a sync function and we will call it down and it’s not going to have any parameters it’s also going to be in a try catch block and in here we will simply say await we’ll call the DB we will also say we are running a query and the query is going to be very simple simple drop the table if exists and the table name is going to be reminders so now we will simply if it throws an error console log and console log error okay let’s save everything and now we can try to run this one as well so it’s going to be the same we were running environment file uh with and we’re running the source migrations and this migration let’s click enter now if we get go back and reload our database we are seeing that something did not work so I think I’ve made a mistake oh yes of course I made a mistake because I forgot to call the one of these functions so either because I only defined them here but I did not call anything so I’m calling now up so now if I run it again and um hopefully it’s going to work well I’m pretty sure it’s going to work okay it’s still creating it so yeah it’s done we can go try to reload it and we see the reminders table amazing now we will no longer create um records of our manually because that’s why we are here we need to know how to create them programmatically right so let’s get into our um um guide and see what’s next yeah here I explain in maybe even too much details of what are we doing here so if you have the guide you can always come back and read it again this guide is going to be always up for you if you download it like yeah and I will keep on improving it so yeah here’s some explanations and here I’m explaining of how to run it the migration and even how to roll back so yeah so for example rolling back I can show you very easily for the create uh for the create reminders we say that oh I made some sort of mistake and I forgot to add one of the fields well you could in theory create a new migration just for that but for me I am lazy so I will call for now I’m uh calling again down so basically migrate down i’m calling this same um migration and then uh we’re waiting a second while we’re waiting uh whatever I pulled that from clients how can we pull the API what do you mean exactly with that brian Harris Prasad thanks for the story bro thank you very much for watching i really really appreciate you guys staying with me on a late Friday or for some early Friday or Saturday uh yeah I really really appreciate you being here guys or any other time maybe you’re watching it after the live stream also so yeah now if we go to our console and if we reload we can see that we no longer have a reminders table because uh we rolled back we dropped this table because it existed so um but yeah but we need it so now let’s say if I made a mistake as I had an example previously I would add a new field here let’s say um not sure what you can add maybe due date something like that due date and then I would define here what it should be but we’re not going to complicate that much so we will leave this and let’s run the migration once again to uh with up to create this table I’m wondering if this is full stack yes we will cover later on um how to create the front end of this application basically your mobile app with all the reminders displayed how to interact between you the back end that we are creating right now and your front-end application uh for each load this migration check if it’s created or not i’m not sure if I understand exactly uh but yes like you would probably check if it exists or not uh always just to be safe um okay so now we can continue with our guide and go into routes this is where the things are starting to get uh more interesting maybe we’re kind of leaving the setup uh ground and um continuing kelber hello hello nice to see you here nice to see you hopefully you’re having guys a great uh evening so in this lesson as I’m stating here we’ll dive into creating uh the CRUD operations and organizing them properly so what are the CRUD operations it’s basically how we will create new data and store it in our database how we will fetch that data and retrieve it how we will update that and delete that so let’s start with a very simple and I will no longer copy my code uh although here it’s a lot of code but uh I want to show you how we do that uh step by step so now we can clo uh actually run our server and if you remember we can run it with mpm rundev click enter and now it’s watching it’s going to be reloading so we can close it we can close these migrations we will no longer need them and we can even close these folders let’s go to the index and let’s try to create different um routes so for example there might be a route uh to post so but because right now I can only get these like I can I’m only calling get routes so to get all reminders get a single reminder but what if I want to create a new reminder well in that case it’s we need to call post or to update you would either patch it or call.put uh then to delete all of them have different um different um basically requests even though for example let’s check at delete and rem and patch they have and even get they have exactly the same URLs all of them so yeah that’s that’s going to be a topic we we are dis basically discovering now a bit more so yes we will need one route which is going to get us all of these reminders and to do that well first of all we are going to call here uh slash reminders and for now let’s just return let’s say get all reminders and maybe I can even remove these comments uh too much i no longer need them okay so we have to get all reminders but I maybe want to get one reminder so in order to get only one reminder we need a way uh to pass the ID inside the URL and if you worked with web apps it’s it will be very familiar and to pass that ID we simply say like this and specify the name of the variable uh the parameter that we’re passing it could be even like name or yeah whatever for us it’s going to be we will be passing the ID because that’s how you will usually be retrieving one items items one item so get reminder by id then we also need uh one more request to create new reminder so we will say call app dot post and we will create uh new post request and a post request uh when are creating we can simply call slash reminders the same as this one then we are getting the request and response and we are say opening an arrow function inside here we are specifying okay what are we returning so we will send back to the requester to the user saying yeah you called create new uh reminder okay now I will like a little bit copy paste because here not much changes for example Here I only need to change the patch and have reminder and actually here I already made a small mistake because here I also need to say we’re calling reminders ID because that’s the best naming structure because for example if you had only like uh this and it’s a good that it’s good thing that I made this mistake it what uh what are we trying to get here are we because let’s say we have also users table so are you trying to get a user are you trying to get a reminder so to be very clear um in your back end to make the life easier for yourself and for your teammates you would usually want to be very clear uh with your naming so here we’re getting the reminder of ID even though in theory we could leave it simply like that um okay so we have a patch that we call to reminders and we also need to say okay so which uh reminder do you want to update so update old reminder and lastly we want to add exactly the same with dotdee and saying delete old reminder so now we have all of the uh most important basically routes and in a way almost all the only one that we’re not uh having is put and put and patch is basically updating both of them but patch is updating certain fields and put is updating the full uh record so now that um that we have these routes defined let’s go in our insomnia that we created a little bit earlier and say see how can we call all of these different routes because we only saw how to call the get ones so if we yeah we saved it we can see let’s go to our insomnia and or whatever if you’re using something different it’s totally fine you you might be using Postman or Bruno it will work exactly the same so now if we call our lo our URL which is going to be local host and we can see that URL uh in here basically on which port is running right now it’s local host but if you had this uh back end let’s say hosted somewhere it would be a different URL so but the everything that’s after it would be let’s say the same um so now what if we simply call slash reminders let’s See and okay it’s calling get all reminders ju just as we are what are we returning basically uh you can add here remember a lot of different codes so for example I could even say okay so before that let’s console log something hello or hello it should be hello so if we go back and now we also want to pass the ID so because if we simply call this with a get it’s gonna um it’s going to call the get all reminders and it’s a very good practice and that’s how you would do all the time create different requests in here for different requests well right so let’s say here we will have get all reminders and it’s going to get us all reminders but now we can create a new HTTP request and let’s rename it and let’s say get reminder by ID So now we need to specify a different URL so but you can kind of copy from here and paste here and just change the last part there is an even easier way in order not to like um remove the need of always defining this here so maybe I’m not going to show it because it’s only on like like that on Insomnia and it might confuse for others that are using let’s say Bruno or Postman but you can add let’s say um environment variables as well and I could use here instead of having always this local host I could have like this base URL and it will encode behind it the local host but just for not to confuse too many people let’s leave it like this so I would say reminders and then pass the ID of the reminder that I want to get so maybe let’s leave it one if I send it I can see that okay the return is get reminder by ID so exactly as we define here and we can also see that it console logged hello as we asked him to perfect let’s create all of the rest uh functions so now that we created both of the get ones we need to create uh a create request and in order to do that let’s first of all copy this URL as always but now this get here change it to post because and you can know to what it to change based on this little hint here so here we are calling post whoopsie patch delete and yeah and get so now we’re going to be calling post and even though the URL is I can simply let’s say go here copy it paste it not change anything and call it we are getting create new reminder and it’s because we are specifying which request are we doing and here we’re doing a post request and it’s also important to rename it so let’s say create new uh new reminder perfect so now we need to also be able to update these reminders if we are able to create them so let’s do go here let’s create a patch as I told there is a put one but we’ll use patch today then we’ll have um the same URL but we need to pass the ID of the reminder and I’ll show you a bit later how to get this ID from the URL that we want to update and it says update all reminder and lastly we want to be able to delete these reminders so we we can simply paste the same URL leave it as delete and call it delete all reminder perfect just rename it real quick delete delete oh my misclicks reminder then here as well update reminder perfect we have all of the requests that we will need for the reminder now we can check what’s next in our guide so now you can kind of already feel that this is crazy uh unmaintainable imagine if I had all of this for a user imagine if u I had even more let’s say reminders different lists different uh I’m not sure like likes or whatever so for all of these I would have to paste them in the same file well that would be in very confusing and very difficult to maintain to solve this issue we will be creating a new folder called routes and this folder will keep all of our routes separated so for example we have reminders routes so we will say reminders routes.js you can have let’s say user routes.js and you can even like have as many as you need and it will keep everything very clean and structured so let’s create these reminder routes what we need to do well first of all let’s go back to our index and let’s copy all of let’s actually not even copy but cut out all of these um requests uh with the command or control X let’s save this folder and go to the reminders route for now just paste it of course we will need to do some adjustments now but because it’s not going to work like that first of all we will need to import uh and it’s a different thing we will be importing router but also from express and router is what allows us to create these separated routes very nicely then we need to initialize this router like this so basically we’re saying this variable will become this router and now we can call this router so instead of having this app app we’re calling uh oh no no no we will be calling router.get router.get by ID router.create router.patch router.delete and I’ll show you in a second why because now we can simplify this uh whole thing a lot well first of all we need to export uh this not uh export this router that we just created and attached all of these routes to but now we can say that router dot slash uh without saying this reminders part router slash id then once again like this and like this so now it’s not yet finished we need to have one last adjustment so now if we go to our index file and inside here at the top we’ll import these routes so it’s called reminder routes and we are importing them from and they’re imported from actually it’s only one routes reminder routes.js so now that we can use these routes and we can tell our app uh instance to use them so let’s say we will say app dot use and we will say so now all of these routes that we are going to pass you here they will have a prefix of reminders and group them together and then we are passing this remind all of these reminders routes so now our application will know that okay if we are calling um reminders basically slash or reminders or just yeah reminders ID uh or whatever it will know that the prefix is like reminders and we don’t need to have all of them added here manually which simplifies the readability a lot a lot more and here you would do the same for let’s say user routes if to created them here you would say users and pass here user routes and once again it would work the same you would have user user/ ID and it would know which routes to call so now that we have this we can quickly go to our um insomnia and check out if it’s actually still working so if we call them like this we can see that they are still perfectly working and we simplified it a lot okay so we Yes we did all of this um Uhhuh yes yes yes we modified it and yeah here’s I’m explaining a bit more of what’s happening it basically appuse mounts these routes uh under slash reminders path so we it knows right away a lot cleaner where to go so now that we’re done with routes with very basic uh routes we will be getting into the meat right now and um it’s kind of important to uh know how to structure your application because if you just create all of the files or everything in one file it’s going to be a huge mess and when it when it’s a huge mess it’s going to be unmaintainable and you will not be able to create a functional maintainable uh and scalable application so usually you would select some sort of a structure to follow and most of the big companies uh right now and not only like also the small startups uh use this MVC plus service structure and um why you would use this I will explain once I’m showing but yes once again it’s called model view controller plus service pattern and it helps to us to structure everything so now I created this like analogy of a restaurant because we will be creating um three more folders so let’s actually do that first of all we will create uh controllers then we will also have the services uh not as a file i created it as a file that’s not good let’s remove it i need to create it inside as a folder so it’s going to be called services and then lastly we will also have models so now let me quickly with this restaurant analogy go over what it means so the controller will handle these requests and send back the responses to the user well you can right away understand that it’s kind of like a waiter in a restaurant so it’s the one that will take the order from the user which is a request it will pass this order to the kitchen to basically create whatever was ordered which the kitchen is in our analogy a service layer and it brings back the prepared dish which is going to be the response to the user this controller/waiter doesn’t process any data doesn’t prepare anything it acts only as an intermediary it doesn’t care really how the data is processed it’s only there to basically communicate uh this order then there is this service layer which is as I said is kind of like a kitchen inside a restaurant which is responsible for the logic and the actual processing of the data so the kitchen the service layer takes the order from the controller a waiter and processes it prepares the food based on the ingredients a model which we’ll talk soon about it can combine multiple ingredients into one and uh it can add specific processes like like cooking mixing garnishing basically all of the logic that you would do for um processing that data or creating that food happens in this service layer and then there is models layer which only communicates with a database uh in our like code example but in a kitchen example you can think of model like an ingredientre different ingredients to make those dishes so it doesn’t care how the food is prepared the final dish it doesn’t care about how it’s served it is simply a dish I mean a product and um yeah it provides essential components basically data to the kitchen which is service layer so that this final dish can be repaired so for example I need a tomato I’m taking it from the fridge and tomato in this case is a model I need some cucumbers I’m taking let’s say reminders and processing them and passing back to the waiter maybe this analogy will help you a little bit easier to understand like why are we separating everything so much and I will also have some examples for example when in the service we need different ingredients uh and we will call different database um tables so yeah we will see how this all ties up in a not a restaurant but in a coding environment so let’s continue so the first um actually the the first one um layer let’s say in our application will be the routes layer because that’s how we will know which route was called so it’s either reminders slash or user slash or reminders ID and then this router will uh specify which controller to use so let’s say let’s go here and let’s create our first controller which is going to be called reminders controller so if we go here um let me check if the stream is still good if there’s any questions or anything so far uh hey Aditia nice to see you here you’ve been here well you’ve been in Discord yesterday so today here very very glad to see you sir Josh uh hi please just join how do I get started please yes uh I see our team member valuable team member just posted um sent you a asset link so just download that and you can have all of this uh what I’m going through um yourself and then after the the stream ends we will post the stream on this channel so you can always come back re-watch at your own pace stop whatever we will never remove this tutorial so feel free to go at your own pace you don’t need to follow me uh like uh in real time let’s see what else uh Ji subscribed thank you thank you very much i’m so happy to see that you are guys enjoying at least some of you not sure if everybody but thank you very very much J uh okay I’m late today what uh we are building today yes we’re building a full stack application a very beginnerfriendly um application basically taking your first steps into full stack development and uh yeah I think we can continue now and um yes what I was talking yeah oh yeah creating those uh controllers uh let’s go to our controllers folder and let’s create a new controller so we will call it reminder controllerjs Perfect um so mean you could have here many different uh controllers so user controller I don’t know likes controller or whatever so all of them also will be se would be separated for us now it’s a good example with reminder and actually um yeah I will tell about it a bit later so now let’s create this controller first of all we’ll say export const and give the name so it will be called reminder controller and now we will inside it specify all the functions so in theory we will try to follow exactly uh let me close this user because we will not need it and actually I can even remove it now because we will not need it um okay we will follow this structure so for example we see okay we have get all reminders well okay that means we need to create a function to get all of those reminders so we will call it just like that get all reminders uh and it should be camel case so here like that uh this will get a request and response the same as we get here request and response and then we will specify what this function needs to do so for now we will keep it uh keep returning this later on we will add like all the data interactions with database but as you remember it’s not happening at this layer yet so we will simply uh have this response still get all reminders so if we save this we can now go back to our reminders table uh remind us routes I mean and then import this reminder controller so we would import it like this saying reminder controller from controllers reminder controller be very careful and add this add this JS at the end because it’s going to crash for you and now we can use it so we can make this a lot more simple so we can remove all of this boilerplate code and simply say reminder controller and call get all reminders that’s it it knows that if the user goes to this route which is reminders slash I need to call this function and that’s it nothing else and pass the request and response to it so we go here and you can go here by clicking command and on this or control on Windows and on the name and we see which function is going to be executed and what this function will do it will simply send a response to get all reminders okay perfect but now we need to do that for all of the rest uh functions so here we can see okay we are trying to get reminder by ID perfect let’s do exactly the same so maybe I just even will copy it and say what we need to do here is get reminder by ID and uh what is it complaining about oh I yes I forgot to add this comma here we need to separate them basically okay now we’re getting uh yeah the response will be this one so we can copy it from the get we can go to our controller and paste that we know that the response is going to be exactly the same and now we can simplify this as well very easily reminder controller get reminder by ID okay saved let’s go quickly create the rest so it will be I think it’s called yeah create reminder we get request and response and in here let’s see what we were doing we were returning create reminder response so let’s paste it save it go to our routes remove all of this boilerplate code now leave this one say reminder controller and create reminder last one not last one before the last one is to patch so we will create One more okay like this we will say a sync and we will call it update reminder we will take request and response and we will return let’s see what okay we’re returning this one let’s paste it back and then we can very nicely once again apply here reminder controller dot update reminder and now it’s the last one so let’s create quickly a sync we will call it delete reminder request and response and then we will have response send and delete all reminder and lastly just say delete reminder perfect let’s save this let’s save this now we can go to our once again insomnia and we can and we can uh test it out so let’s say if the lead is still working okay they are still all working amazingly just as before um yes so let’s see what we need to do next we created all of these reminders uh all of these functions i mean we are using all of these um controller functions inside our routes uh and now we say yeah basically I’m telling here what we’re doing so feel free to read it out um so now it’s time to actually handle some data from these requests because in many scenarios we will need to get uh the ID for instance when we are creating when we are updating or deleting uh a reminder from the URL or maybe we will even need to get some data from the user so for example when we’re creating a new reminder we need to get the actual reminder and the notes for it so we need to somehow get this data and to do that it’s actually very very easy well what we need to do is we need to get it from the request then all every request will have this params and then the name of the parameter that we are passing in that URL so let’s see how to do that look for example in the get get reminder by id and also I’m here parsing to int because if you know like all of these um are passed like ID not like this but one two they’re a string but we need to convert them to a number in order to actually pass them to the database sometimes databases also store the ids and strings so you would not need to do that but for us it stores that in an integer in a number so we need to parse it to an integer as we are doing here so if we go back we will say here uh const and we will say what the the name of this variable so we will get call it reminder id and as I said we will par parse this id to integer and then we will take it from the request so from here and in the request there will be parameters and we will okay so how is the n what’s the name of the parameter so if we go here and we check for get reminder by ID we called it ID okay so that means we can copy this come back here and say that request parameters should have ID and in order to test if we are actually uh getting back this ID we can a little bit transform this and add these different quotes under escape i’m not sure how they’re called and we say get reminder by ID and we specify with this syntax of inserting this variable uh reminder ID so now if we save it and go to our insomnia we say get reminder by ID and uh we pass the ID one if we save it we get ID one if we say let’s say ID5 it’s working perfectly that means we are getting this ID we’re parsing it and everything is amazing from the URL part you could pass many different URLs so you could have here uh also like ID and then um name and u yeah like different names but you would get them exactly the same like request params and then the name of the parameter that you passed okay so this is working for the ones that we need to pass the reminder so we can copy this and do the same for the update reminder because if we remember for updating we are also passing the ID and we see that for delete we also pass the ID so we can pass the same thing for delete but now for create it would not make any sense to pass all of that data in the URL first of all it’s not secure at all if we would say uh here let’s say like uh reminder and then pass like everything embed inside the URL and then take it like this no no no no very bad so we have a way better way of doing that and we can pass JSON format to these requests so to to achieve that uh we will need to of course have some uh changes and I talk about the change um well first of all maybe ext let’s extract this URL and then I will say what we need to do but actually extracting this URL is very very easy so in create reminders what we would do is we would say um let’s create let’s say new variable called reminder and we will take this reminder from request once again but now we will not take it from URL parameters but we would take it from the body of the response of the request and then we would say the name of the variable that we passed so in our case we called it in the database as you if you remember reminders so if we go here and u let’s reload where’s the reminders table yeah here we have the reminder and we are expecting that to be passed when creating a new reminder so now we can simply console log this reminder right but let’s see what will happen now if I do that so let’s say I go to uh create new reminder and of course I pass this so we need to pass it as a body we will pass it as a JSON body and I’m saying okay so I’m passing the reminder and the reminder would be uh take the dog out for a walk i don’t have a dog but I would love to so yes let’s see what will happen i send it and I get um I get an error cannot read properties undefined of reminder so why is that happening let’s try to console log the whole request body so let’s now have it like this go back call it go back here and see the console log reminder is not defined uh and um oh here let’s say request send like let’s do like this go back send this request and we can see that request body is undefined but why is that well um express doesn’t parse the incoming data to JSON by default so we need to enable that by like basically passing the the middleware and the middleware ware it’s also um yeah let’s say what is let’s talk about what is middleware in general middleware is kind of a helper functions that help you process the requests before they reach the routes so for example a request comes in we process it here and only then we pass it to the routes if like the middle it passes the middleware but it can throw an error inside it it can perform different checks and we will even see how to create our own middle middleware a little bit later but for now we will uh add a new middleware that will that express provides to us and it’s going to be the app like how do you apply it is simply app dot use and now we need to say which middleware to use so we’ll use one from express and we’ll say where we want to use the JSON middleware what this does is it parses the incom incoming request to JSON uh which will help us to make this defined basically and uh let’s try to save it and try it out right now so if I leave it like this I can even do like this and go back here i send the request we can see the reminder of take the dog out for a walk that means everything is worked because as you can see now it parsed this um this uh body into a JSON file that express now knows how to read and know how to return to us so we can use that so if I would say let’s say pass here also notes and let’s add something like don’t forget to feed him before and let’s say I pass it go back here we can see that now it has a reminder and a note and I can pass even more like a lot of them so um okay now what else let’s see let’s see our um guide and maybe we’ll answer some comments yes here I’m explaining like how to add the middleware what is it and here we will go into service layer so before that I think we can take a short break uh sip some water and check out some of the comments yeah I see Danielle said it’s important to stay hydrated so I’m trying uh Jade thanks for the MVC plus services no worries no worries i’m trying um I’m trying my best hopefully the explanations are also clear enough enough i think my back end will be much cleaner after this hopefully hopefully you can use a number uh which will enforce to be only number any char will throw an error yes that’s also possible yeah uh so uh what what’s next i think uh oh Adita also commented great to see awesome content thank you very much Aditia appreciate you a lot always supporting always here uh yeah very very much so let’s go back to coding right so now we will be introducing the service layer and here you can also right away see what is this service layer i already explained it a little bit more inside um like my restaurant analogy which hopefully was good enough but basically a service layer it will contain all the logic of the requests to like yeah I’m doubling down but without let’s say analogies uh it will be responsible for performing the operations on the data and coordinating everything between the model and the controller it’s basically a layer in between uh model and controller which is the main logical part like where you would do calculations and stuff like that and here I’m listing some of the responsibilities as well like will perform core logic coordinate and aggregate the data with different models so you can call different functions in a model like get something then update it and delete it and uh yeah so it will also interact with the third party services or APIs and return process data to a controller so it’s a very important layer and some of the um applications skip this layer but and do let’s say all of that logic inside a controller i would never do that and more most of the more let’s say modern and um bigger corporations will always have the service layer because it makes everything so much cleaner and so much structured uh a lot more reusable and uh it’s a very good practice to learn it and always use it so yeah that’s that let’s see how to actually implement it and add it so first of all as we can see here we are we need to create actually we already created the services uh folder but inside here we need to create our reminder service so reminders service.js okay and now here let’s create um let’s say the functions that will be responsible for doing all the logic so let’s create again let’s say export const and we say reminder service and then we do like this and um here we can all like specify and define all the functions that’s the word I was looking for a sync we will have get all reminders so if we get here we see okay we have a function to get all reminders that means we will need to get all reminders And uh it will for now not get anything and inside here for now let’s just leave some comments and say fetch all reminders and for now let’s because we don’t have yet the model which will interact with the database let’s return only an empty array and let’s continue creating for all of them and in theory you can just copy paste to make it faster for you but um yeah because you asked I will uh do it like this get reminder by ID and actually maybe it doesn’t make sense to waste the time on this basic uh implementation um just definitions basically so fetch reminder by ID maybe I’ll just go here and copy the rest so we’ll have the create reminder update reminder and delete and once we are adding some logic inside there I will uh keep on writing because here we simply basically copy what we defined here the functions as well so not to save some time and leave some energy because it’s already getting late for me to explain let’s say front end as well a bit better let’s do it this way here now i hope it’s not going to be a huge issue for you guys so yeah now that we have this service layer um we need to connect it with our controller layer and now we will be start adding uh proper structure and final structure almost final except for the errors of our um controller functions so all of the controller functions will have this try catch block because we need to try to execute this function that we will pass but if it fails controller is responsible as a waiter let’s say if the cooking is bad if it I don’t know if we don’t have this uh ingredients the waiter is going to be the one who will come to the user and say sorry we cannot prepare this for you it failed because of something so yeah that’s why we are having this in the controller because it’s it’s talking with the user so first of all we will try to actually get these reminders so we will say const reminders and we will be calling the reminder service but to do that we also of course need to import them so let’s do import and then we say reminder service from here that we just created once again if it auto corrects add the GS at the end and now we can start uh saying reminder service and we want to get all of these reminders so if you get them if everything is good let’s return response the status and the status codes we will also talk a bit more uh about them later but probably you heard about like 404 200 500 uh there’s different status codes to communicate what uh error was it so for example if everything is good 200 is okay that means everything worked out and we’ll return the status 200 and we’ll return the JSON of these reminders so that means everything worked out but if we got an error we will need to return the status of 500 for now we don’t know what was the error so we will simply send 500 error which is like a very general internal internal server error so what a uh mouthful so we’ll say here as well internal server error and we will see later on how to make this a bit better so now that we have this we need to apply this logic for all of our routes so let’s go and do it so here again try catch block we’ll be trying to get the parse the ID and we’ll be trying to get the reminder by which by ID so we’ll say not controller reminder service dot get reminder by ID but now we need to pass the reminder id for our service layer to know with what ID should I call the models should I call the database basically so we are also passing down this ID and then we are if everything is good we are returning just the same only changing what we return which is reminder and not like all reminders but the error for now will be exactly the same we can remove this uh basically if it didn’t work uh just call it with internal service error let’s do the same for create reminder and in here we will need to uh get the body request but now we like it would be a bit un um how to say redundant to do it like this notes and say okay give me notes it’s not a very good practice it’s not let’s say maybe horrible but there is a lot of a lot easier way and also we would not be extracting in this layer because we’re trying to keep it uh very um clean so what we would do is we would again call const reminder and then we will say reminder service uh create reminder and we would pass all of these um all of that like JSON body which is request slashbody and it will contain all of the data from the user like a reminder user ID and notes and we pass it to create reminder and then create reminder we will define the logic how to handle this so now if everything uh worked we’ll return f 200 if something failed we return 500 and we delete the rest there so now it’s actually uh these two are very similar to update uh so let’s add this try catch block let’s try to parse the ID and let’s try to uh call um yeah const reminder and we will be calling the reminder service dot and it’s update reminder and we will be passing the reminder ID and for this is going to be a little bit different because update reminder well we need to know which uh which object are we trying to update so we need reminder ID but We will also need to ask the user basically for him to pass us the updates that he wants to do so if you are updating the reminder itself let me know what what text should I change it to if you’re updating the notes let me know to what you want to change it to so what we will do is we will also pass the request body the same as in the create reminder because here he’s passing his initial basically reminder data but here we’re passing already the updated so if we go to insomnia and to update reminder we would also have exactly like this so reminder and then something like new reminder and then in the J in that oh we don’t need this in that JSON we would get this reminder and if pass it to the update reminder service so if everything is good return this if something went wrong return this and lastly for the deletion it’s try catch and then having this here and then lastly calling the con reminder and calling reminder service and where is delete reminder with the reminder ID of this okay like this and like this yeah I’m actually not very clear like clean with keeping these here so it’s not an error it really depends on what your team is which pattern your team is following you might not be adding these uh you might be adding these these do not change your code logic in any way so yeah it’s really up to the teams and we can also remove this one so now that we have our controller basically almost completely done we will change the errors we can continue and check out what we are doing next so we updated all the functions in the controller uh yes we talk a bit about here now controllers don’t have any logic and don’t handle any logic they only call services so now it’s time to introduce the model layer and the model layer as I talked in the my analogy it was it’s kind of like an ingredient like a product it represents the data layer it it is responsible only by to interact with the database basically it only runs the queries u to store update retrieve or whatever here is the place where we will define our raw SQL queries and as you can see the responsibilities would be to interact with the database and this like a prov provides a layer of abstraction which is basically I only what it says I only know how to interact with the database don’t give me anything else you call me I give you like the result back that’s it so this way we can reuse them very easily so for example maybe even in user uh control user service I would need to get uh somehow some like for some reason his um one of the reminders so I could call this find by ID um or even get all from the user ser uh service and uh or even in the reminder service I can call multiple of them so for example maybe I need to get one reminder by ID and then maybe I need to check if it exists that’s actually what we will do and then maybe I need to delete that reminder so yeah this is uh what it’s the model layer is responsible for so let’s do all of that so let’s go back to our code and inside the models we need to create a new model which is going to be called reminder model.js so this reminder model uh we can start defining the um the queries itself so let’s first of all import the database because as I said here is where we will talk with the database so we’ll say config database njs very important then we will say export const and we’ll say reminder model and it’s going to be uh like this so here now inside we will we can specify all of the functions so first of all it’s going to be get all and in here we don’t need to pass anything it’s simply going to call the database and return it so first of all we will say we will store the result in this variable and we are calling the database so DB dot we are passing this query to the database and now we need to specify what query so first of all we will say we want to select everything all the fields basically uh like uh the reminder the notes the user ID everything from uh which table so we have two basically you could even either specify reminders or user or if you have created more tables you will tell here pass the name of the table so basically what you have here okay we say take all from reminders and uh that’s it we only need to get all by reminders but we also want to order them so basically to return them in order by how recent they were created so we want the most recent reminders to be at the top maybe you want a different order that’s also totally fine but for us that’s what we want so we would say return where ordered by created at in a descending order so now this will uh like this will be the the query uh SQL query and we would simply return we would call this database we will try to get all of this and we would simply return uh all of the rows from this result so no no no so we’ll from this result we will return all all of the rows because that this will always return an array for us in this case we want an array later on we’ll see what to do if we want only one object so now uh if we try to do get all we will not get anything just because we still didn’t connected it to our services but soon we will do it we still need to define some more functions so one of them is going to be find by ID and in here uh it’s going to be a bit different because we are actually going to get the ID because we want to know on which ID do we need to do the query but the rest is going to be very similar so it’s going to be result we’ll say DB query and here once again we will follow very similar pattern we will select all fields you could specify here let’s say what field does reminder have like only the reminder notes so we could say reminder and notes uh and then you would follow something like from but for us we need to return all of the fields so from reminders table uh actually here I forgot I removed it because I already see we need to get all from reminders table so yeah here we select all from reminders table but we need to get only where this ID like we give the name of this field so we say where the ID of that field is equal to um this weird syntax to basically we’re saying to the value at position one but now we need to also somehow pass this value in theory you could have added in here something like this uh of course by changing this but it’s very unsecure because of SQL injections so this it makes it a bit sec more secure and how we would pass uh the values we would simply say here so the value at position one later on now actually when we will be showing the create one you’ll see how we can pass more more uh fields more values so now just simply return uh not const but return result dot rows but as I said we are returning again an array but in this case we should expect one object not an array of objects so we would simply take the what we’re saying here take the first um object from rows array so why it’s not one it’s because that’s basically how programming works and we count calculate count everything from zero not from one so zero means at position one means at position two and so on so start counting from zero if you’re yeah total beginners get get start get you uh start getting used to that that’s what I was looking for okay now let’s do for create so we create once again a create function and in here we will once again say const result equals DB query and we will specify select uh actually not select because now uh now we are inserting now we are like creating adding new data so this is going to be a bit longer and um let for that let’s make it um structured let’s say a bit better uh but maybe let’s write first of all in one line and then I will structure it so what we will say we are inserting now not selecting in so now we need to specify instead of from we will need to say into which uh table so we are inserting into reminders table and now we will say um what values are we inserting basically so we specify the values like this it’s going to be reminder just as we have uh where is it in here reminder notes and we can also pass uh in here the user ID which we actually need to do so reminder um notes actually notes and then the last one is I said user ID and the names here once again you can get like they should match what you see here at the top so now that now that we defined these um what we basically need to insert we can also specify uh the values itself so it’s going to be similar to kind of this but a bit different now we say okay so insert values so this value is going to be at position one and then the notes will be at position uh two and then the last one will be at position three and after you do all this query please returning returning please return me everything here you could also specify as I showed you here what to return but we need to return everything so now how do I pass uh the values in here well it’s following a kind of similar uh actually exactly the same pattern as here so we give comma we open an array and now it’s the the the order is going to be very important actually first of all we didn’t even like get these so we can dstructure them by saying that give me a reminder because as if you remember in our insomnia when we’re creating we will pass the reminder the notes and stuff like that which are going to be required so yeah we are passing the reminder the notes and lastly we will pass the user uh ID and as I said the order in which you pass here the the values is very important because if we say here let’s say notes reminder and then user ID and actually it I think it kind of makes sense right away to u make it a little bit cleaner and to do that I will need to change it to this and also okay so insert into reminders with these values and then return me this looks a lot cleaner so it’s a good good thing always so yeah what are we doing now is we’re saying notes because we said here that the reminder will be at position one so now it uh it means that notes will be applied to reminder that’s why the position in which you pass here the fields is very important so we actually meant that the reminder should be at position one just as here the notes will be at position two so let’s do like this and the user ID will be at position three so we are passing here the user ID and um yeah that’s how you insert something but now that you insert it we also need to return the the item that we just inserted so we’ll say uh return result dot rows at position uh zero just as we had here and lastly is the delete so it’s going to be a sync delete and we’ll have here again we’re only going to be asking for rem reminderinder ID and I already see the issue a sync reminder ID and in here we’ll be specifying once again our uh query so we’ll say await actually I didn’t add it here as I see anywhere a wait and it’s very important to add that so because we need to await until we get the result and only then return maybe there someone even commented this maybe let me check uh nope one uh Muhammad following from Dubai oh that’s very nice that’s very nice so yeah this is very important to this little keyword to await or underway to just wait until this query is executed and only then return so we need to do that for all of them uh await await we would have spotted this issue later on but yeah I’ve I’ve seen it here so now we say the B query and let’s define uh I think it’s not the last one because I probably I need yeah I skipped update I think so but the delete will be um something similar but with a different keyword so we will say delete from once again now we say from which table to do we need to delete it from reminders uh whoopsie and then we will need to say where ID equals it’s like updating a one once again when you’re just starting out you can try to write these queries with the help of um CH chat GBT just ask what kind of um what kind of uh query would you like to build and it will return you like all of this you can even join the tables to like return different things so it’s um yeah it can help you very much but now once we delete we simply want to because now we deleted this item we simply want to return the result and the row count of um the deleted items basically how many were deleted okay and yeah I skipped the update so we’ll say a sync update and now we will be again once updating we need to get um the the update values but this is going to be a bit different because we are going to be patching so I’m not sure how to show you so for now maybe let’s leave update implement later because it’s going to be the only one that’s kind of different in a way that we will not specify the query here and I’ll show you later why is that but yeah now that we have all of these created let’s see what we need to do and yeah oh yeah here you see how it’s going to look like but I will not add it yet i will explain to you a bit later so now we can add these models and start using them in our service layer and um to do that uh actually let’s do that let’s do that yes so if we go back to our service layer here we can import the model uh in here we just go import yes reminder model and also don’t forget to add.js and now let’s start using them well first of all the yeah the first one is going to be very easy we don’t need to pass anything we don’t need to do anything it’s simply return reminder model get all and we get all of these uh reminders and return them right away for reminder get with ID it’s a bit different because if you remember from the controllers when we’re getting by ID we’re passing this reminder ID so if we go to the service we can get this reminder ID from here that we received and now we will say okay so I will assign this reminder and I will await again it’s very important to wait for the response and I will call reminder model find by ID and I will pass the ID so I will pass this reminder id to the model so if I go to uh find by ID we can see that it is expecting the ID and that’s how we will find so let’s go back to the service and if now we need to check if there’s any errors so if I for some reason this reminder is not returned that means something was wrong something did not work out so what we will do is we will throw new error and we need to specify what is this error so for example a reminder not found because we let’s say did not found the reminder something is bad and we will throw the error but if we found a reminder we will simply return it and um yeah and we will return it now soon with the creation after we implemented this we will see everything in action with insomnia so now after create uh after getting it by ID it’s time for create implementing the creation of the reminder so if you remember from the controller uh we are passing the whole body to create reminder so in here we can get this object of reminder we could either destructure everything inside here and take all the values one by one or you can have something like const and in here specify what we are receiving so if you remember we’re expecting the reminder the notes and also the user ID the same if you go here the create expecting reminder notes and user ID so actually yeah here I showed you how to dstructure them inside the uh when we’re receiving here I will show you maybe then a different approach uh how you could do it so and actually I’m doing that right away uh so doing this way and what this does is basically instead of having const reminder and then equals new reminder dot reminder so it would be even wrong maybe something reminder object so it’s and then you would have something like this for notes and here notes and then the same for user ID it requires three lines of code that would be imagine if you have like a huge uh form of 10 inputs getting all of them like this is it would be a nightmare so what we’re doing is instead of assigning them each to a new variable or of course you can have it in here and pass it just like this uh as well to a function without assigning to a new variable so for example if let’s say we call what function do we yeah create so we say we create this uh const created reminder and we need to call the reminder model.create so you could pass them like this one by one and then reminder notes but it still doesn’t change doesn’t change the fact that it’s very long so we can destructure all of them outside so what we’re saying here from this reminder object take out these values so it’s very important to have this curly brackets around here and now we can use the them right away without doing them like news reminder new reminder notes and repeat ourselves we can simply say reminder notes and then lastly user ID so it right away knows like okay I’m taking these values here and I’m passing them so it saves us a little bit of time uh yeah so I highly suggest you doing that in theory you can also as we did inside the model do them right away in here you don’t even need to have this line of code so there’s a lot of um ways to do it but just know that do not do new reminder reminder new reminder notes new reminder user ID choose either this one or the one where we d the structure right away inside the function okay okay so now that we are calling this we uh need to return it here but also um as I told this and I want to show you as an example this service layer can have a lot of different things like you can clean your uh inputs you can do a lot of different calculations so just to be a little bit um show a bit more of an example I’ll do let’s say it’s common to sanitize the input form so for example let’s call const sanitized uh reminder and what does it mean is we’re cleaning up the user input so for example the reminder user can pass us like something like this space space space space hello space space space and maybe we don’t want that uh we can very easily sanitize this and clean it up we will say if the reminder is passed just trim it and trim means means clean the empty spaces before and after let’s do the same for notes maybe we don’t want to have like that many spaces at the start and at the front it just doesn’t make much sense for us in our case let’s say so we’ll say trim and this question mark means uh if it exists kind of so if it would be null and we would call uh trim on null it would crash but now this prevents from crashing and lastly uh for user ID think for user ID we are simply passing it as it is like that so now instead of passing them like this we can pass them as sanitized basically cleaned up uh versions so yeah this is not necessary i just wanted to show you that you can do a lot of things in the service layer you can have a lot of different logic you can have here running like I don’t know huge for loops and stuff this is where it would happen so yes um if everything is good here we are returning the the the reminder we can also have like this error handler here saying that if create reminder does not exist something like something crashed in this case actually our controller if something would crash still catch it so we don’t really need this check here and here we need it because if the reminder was not found we need to be clear with our error but here when you’re creating a new one it cannot be not found because it should be not there yet if you know what I mean okay so for updates um are we yeah probably let me actually first of all showcase you how we create get and get them by one by ID and then get all of them and then maybe I can show you the update because that’s going to be the most complicated one so if we go back to our insomnia first of all if we try to get all reminders let’s check that we are not returning anything so we’re returning only an empty u JSON so if you remember we changed it in the controller layer and now we’re returning a JSON it’s no longer uh we’re no longer returning the response send and here like some HTML code we are right now returning a JSON of the reminder but because we don’t have any reminders it’s empty now so now let’s create a new reminder so we will add reminder uh take the dog out for a walk note the same one and let’s check the id of the user so the id is one so we also need to pass the user ID and for now we don’t validate this data in any way but later on we will add so for example for now if I would um not provide something it would not crash it would crash but in a let’s say database layer model layer so now if I say send we are uh not receiving uh oh yes we should post that’s good uh if I go to reminders we can see that the reminder was created and sorry and we can see that the data is exactly the same so we are reminder is take the dog for a walk the note is don’t forget to feed before it’s not completed the user is with an ID one and it was created so now if I would go to get all reminders and send this request for some reason it’s not working so let’s see uh what’s bad here so if I say get all reminders reminder service get all reminders and now get all select everything from reminders order by created at descending okay let’s console log the result here uh console log result and let’s see why is it probably I’m missing something oh yeah let’s do rows okay let’s see let’s see it actually it has it in here I return it okay so in the service layer okay Maybe uh where is it and it is in if yeah in service layer okay so yeah I already no actually I don’t see the error because we should be returning all so now if we go to controller let’s see here if we get console log and let’s see if we get those reminders the probably it’s a Oh yeah here it’s a promise but we are uno so yeah probably I’m missing something like crazy small okay so is it Yeah let me check the controllers real quick yeah I already see the issue and it’s right basically saying me here we are even though we are calling here like a reminder we are not awaiting for the response so we need to wait until we get the response so this is a very important thing and only after we get it we will return it so add it for all of it await and that’s why we also when creating did not receive it so sorry for missing that in so go to reminder controller and for every part where we call uh our service layer add an await before it so for example now let’s test it out if we go to our insomnia and if we go to create new reminder and let’s say uh buy milk and um hello for user one if we create it yeah we are also receiving it back so that was my first hint because I was a bit also confused why didn’t I receive it but now if I go to get all reminders I will get all of my reminders There’s and even so for example now I can say okay I have reminder with ID 1 and with ID two so if I go to get reminder by ID and say give me with ID2 it will return me a reminder with ID two if I say with ID1 it’s a first one but if I say with ID that does not exist it will throw me an internal server error but we will handle it a little bit later properly so um okay what’s next what’s next so now we need to see how to update it and actually update one is going to be the most complicated because uh we we need to get basically okay we need to allow a person to pass only certain uh fields so for example if the user is updating only notes field it should update only notes and do not touch the user ID or completed or um even the reminder itself or if user let’s say completes a task uh so we need to update only the completed field we don’t need to update the notes or the reminder fields that’s why in here and me I do not specify too much but in here that’s why we are building this SQL dynamically basically so we have we’re taking all the fields from object keys with new values and keys will so maybe actually let’s try to write it and then I will console log it with it will be a lot more easier for me to explain it well so now for the update reminders we can go to the service layer and in here start implementing it so the first thing that we will need to do is once again get all these values so I would say here const and the values that I can get are like the reminder the notes and I think it’s also completed nothing else i cannot update the user ID and nothing else so only these three values and I will get them from the new values and later on we will see how can we define the schema of what we should allow to pass and what is required what’s not required we’ll see it very soon so now that we get like these values we need to according to them build our SQL query dynamically so first of all we will say const and we will take all the fields and we will say object dot keys and let me first of all write it and then I will show you so new values if I console log these this uh fields actually it should have been let’s save it and let’s go to update reminder and pass let’s say yeah new reminder so if I pass it here and go check it out the fields are basically these so I’m saying the reminder notes and completed I’m taking the key and putting them as a name so for example let’s try to pass the notes as uh notes and saying here uh updating note yeah I made a mistake but it’s not a problem um actually I’m getting some sort of updating note okay let’s make it the same let’s try to send it yes it fixed it so now if I go here I say okay so the keys are reminder and note this is a key basically the name of this will be a key uh basically here this is a key here is also a key okay so now that we have these keys we need a way to get um also the values not the keys anymore of this object so what we will do here is first of all we will uh call const and say values equals object dot uh values and we will pass the object that of the values that we want to take so and maybe also actually let’s do it like this after the this one and after this let’s console log but here fields so now if we go and call this and go back we can see that okay the key is the reminder and the notes but the values are the new reminder and updating note so actually the values are the this part uh and basically what this object dot does is it takes the object and makes it into transforms it into an array with either like keys or values so now now that we have these we need to a way to create a set clause and a set clause is um basically when you’re updating you need to say okay so actually I think I have an yes we’re saying update reminders and we need to explain what needs to be updated like what needs to be set so to do that we can go back to our code and to reminder no no to the service and we need to create the set clause so to do that let’s say here const and say let’s call it set clause equals and we will say fields dot map so we’re mapping through all the fields that we pass so you it depends on how many you passed maybe it’s only reminder so only one or maybe it’s reminder notes or maybe it’s only completed but it will map through all of them and mapping it’s mapping it’s kind of like a for loop uh a bit different but in yeah it’s mapping through all of these items taking first second third and doing something with it transforming it so what we’ll do is we will take the key so the name like reminder note or which is going to be here and then we will take the index and at which position we are uh in this so this will be at position zero this is at position one and this is at position two so this is going to reflect that and we will transform as I said in this map so we need to open this like under escape quote and we will need to say okay this is where I’m going to pass the not a string because if I would simply say here key it will act as a string but we need to say that we here we’re passing a javascript expression so we’re taking this key so it’s going to be a reminder and then what we need to do is we need to say equal and if do you remember how we in the models how we did like where id which is the key that we’re trying to do and we need to pass the position of it so where the position is one or even here a position is two three and it can be four five six seven so what we’re saying here is if you remember this is the we need it in a string because this is how it’s done here and then we are need to open the JavaScript expression so this is no longer a string this second dollar sign and in here we will say where the index uh and plus one because if you remember I said like it start counting from zero but here we need to start showing from like a normal person one two three so now we created the set clause and why this set so we can console log it and actually I will show explain you why is it important to do it this way so if we go to insomnia let’s call it once again open it up and we can see that this is the keys this is the values and this is the actual set clause so we’re saying okay literally exactly like here we’re saying where ID is at position one but here we’re saying where reminder is at position one and it notes at position two because we don’t have the user we did not add here and you kind of already m can guess why we do this thing because user can pass only one thing only two things or all of them and we need to dynamically know uh build this set clause because if we would add there uh let’s say uh set and pass them all by one so uh let’s actually build this query and then I will show you so con query equals and then we open this uh query and then we’ll say so in this case we’re updating the reminders table and here we will be passing this set clause and here we need to want to pass this set clause and uh again we want to specify the JavaScript expression inside it so this is the syntax for that we’re saying set clause and we want to also be because now it’s an array we want to transform from this array into a string so we would set set clause and join every item inside an array with a comma so I can actually even consolate log console it for you to see so we would say set clause and join all of the strings inside this array which is in this case this one so this is first item this is second item join these items by a comma so if I save it send it go back here we can see that now it’s a string and they are joined by a comma i could say join them by this but of course it’s not going to work for us because um yeah and you can see it’s joined like this but it’s not going to work for us because this is what SQL is expecting to be separated by a comma or let’s say here like this okay so now that we have it uh like that what we yeah so we are setting set clause and we want to specify which object to update so what we will say and to which values to update we will say where first of all uh and I actually actually forgot to add one more thing because here we will say where id so we are saying which object to update and we will say where id equals and we could either again inject it in here like this uh say like the ID reminder ID but it’s not secure it’s prone to SQL injections so that’s why we will do a little bit different and after we add all of these uh values basically to um to the values that we will pass so reminder text like this reminder no uh this new reminder update note at the end of it we also want at the end of this um array we also want to add the ID of the reminder so let’s quickly run it again and see how it looks now so now this looks um yeah actually values I’m not console logging uh here no wait let me clean it up here we don’t need anymore set clause we don’t need anymore to see fields for now like this so values push and then we are adding the rem no reminder ID okay let’s save it let’s send it let’s go back okay so now we see that the values are new reminder the same as we passed here then updating note and the last one because push adds it to the end of the array is going to be the reminder array the reminder ID from here so for example if I add two here and go back it’s going to be two okay so now we will say so the ID of the object that we want to update is again this little uh syntax but now we also say that okay now this is going to be an expression it’s going to be you could either do values and at position uh values dot length so it’s taking like from the array of values so from 1 2 3 we would say and because the length of this is uh three so actually let me console.log yeah this I hope is not over complicating things to you but we need that so if you console log you see that the length is three three and we are saying that take give me the at values at position length three but let’s see what will happen if we do that uh so I console log I do here and it’s undefined be why well because here the length is actually three but if you remember we are starting to count from zero so you would need to add minus one so now if you do this the will be the ID of two but there’s an easier way to do it so what you could do and that’s also another helper uh we could say simply where values dot so actually let me first of all maybe even console log it it would be easier uh length so if I do values dot length and I console it log yeah it’s going to be three but um I I think it it should work um so basically what I want to do is take the last item of the uh of the array so let’s leave it for now with this approach but um later on we will check it out i think it will work minus one so now we’re taking the last item and this is going to be the the last item we always know it’s going to be the reminder ID so where id is this and then don’t forget that returning we will return everything there so now we have actually built um query so now let’s console maybe even log it a dynamic query that will change based on the it based on the inputs that we pass so now the quer is update reminders set the reminder at position one notes at position two and we know that the values so we actually also need to console log the values but the values would be that at position one we would have a reminder and at position two we will have notes so now if we let’s say pass only uh notes only reminder if we go back we are seeing that okay so set reminder which is at position one and um yeah the values at position one is is is a new reminder and the same like basically as we say here so it’s taking the new reminder yeah so it’s a little bit more complicated than the the rest and I hope I like I managed to Uh I hope I managed to really explain it well because it’s it’s going to be the most complicated one and but yeah but now that we have this query and these values that we want to add so let’s remove all of these console logs that we will no longer need we can pass um so basically let’s do const and then we will say updated reminder not update but updated reminder equals and we will say await very important not to forget reminder model and here we will say update but now to this update we will pass the query that we’ve built here and also we will pass the values that we’ve built in theory you could build this query inside the model and it would it would be probably like still good way of doing it but I wanted to keep the models like very very low level no logic so it really depends on the team where you would do this uh building this query uh but um yeah neither one of these choices would be a bad one in the model or in the service in the controller that would be bad so okay we are doing updated reminder and now we’re saying if we are not receiving an updated reminder we will throw a new error so we basic basically throw new error oh error and it will be saying reminder not found because probably we did not found the reminder that you are asking me to update but if we found this reminder we will simply uh update uh return the updated reminder now that we’re done with this we can go uh inside our model of update and implement this model as I said we’re skipping it now but it’s going to be very e easy right now because we are taking the query and the values as we’re passing here query values and we simply need to call the database so basically say const uh result it will be again await db and then we’ll say we’ll do query and then the query will be very simple the query that we pass here so basically the the one that we’ve built here and the values as we were passing them uh in here as a second parameter the values is also going to be an array of these values which is what we need so if we go here uh no here we are going to pass the values here and now last thing to do is return the result and the rows at position one so now if the update is done we will return it so now we can try updating it so for example let’s try to get all reminders uh the first one is buy milk and the notes is hello so if I go to update reminder for two let’s say the notes notes is don’t forget eggs so if I update it I already get the second one where the reminder stays with like milk and the notes is don’t forget eggs now I don’t can update also the reminder itself uh saying by cheese and it will not update other values because if we would have not created the set clause if I pass only the reminders it will set everything else as null because I’m not passing notes it would set notes as null completed it would set as null so it’s very bad way of it would be bad way of doing it and maybe if we have some time um I will I will showcase but probably will not have time for that anymore because we’re whoa quite a lot long time in okay so now that we have this um this update service uh done the last service that we need to implement is actually the deleting service and do we have the controller for delete yes so this is also going to be a little bit different uh because what we need to do here is we need to check for a few cases first of all we need to check if the user can if the user that is trying to delete is actually the one that created this reminder if not we should not allow him to delete second thing is we need to check if the reminder that we’re trying to delete actually exists and if the reminder like the deletion was successful so first of all uh because we right now don’t have any kind of authentication we don’t know the ID of the logged in user or of the user that is trying to do the request so right now we will simulate it by saying authenticated user ID and we will pass the ID of authenticated user let’s say that is right now so first of all that we need to do is we will check if the reminder uh is actually exists that we’re trying to delete so first of all we will call reminder and now if you remember I told you that why are we separating all of these in separate uh like in the model it’s because now we can reuse everything so for example now I can say reminder model and give me this reminder with this ID i could call a lot more functions like other model functions in here and it makes everything a lot cleaner let’s say and more scalable because I could say okay then let’s um if we were trying to delete but it was it failed let’s update it maybe some field that um say that okay this user I don’t know like it’s it’s up to the um up to your client how he wants to handle but what I’m trying to say you can call a lot of different models inside these services so now that we got this reminder what we need to check is first of all if the reminder exists so we’re saying if it not doesn’t exist so this question uh exclamation mark says that if the reminder was not found if it’s not here then we will throw an error so we’ll say throw new error and then the error will be let’s something like you are not authorized okay if the uh oh no this is not I mean reminder not found yeah so I if the reminder is not here that means the reminder was not found based on this ID okay let’s move forward now if it find if it managed to find this reminder we need to check that this reminder and the user ID so basically if we go to our console if this user ID so it’s very important to have this exact same name if user ID is not equal to the authenticated user basically the one who is do trying to do this request then we would say um again throw a new error and here we would say uh you are not authorized or something like this okay but if the user actually the user ID matches um this authenticated user ID that means we can allow him to remove it so we would say we would call like as always const maybe let’s call it now row count because now we will be receiving the number of rows deleted so it’s a more appropriate name so we’ll say await and then reminder model delete and then we as we if we go to this delete we can see that it’s expecting the reminder ID so we can say here let’s pass this reminder ID to our model and now that we pass this ID we can check like another last check if row uh this row count is equal to zero basically it did not delete any uh reminders we can throw yet another error saying that failed something failed like failed to delete a reminder maybe yeah we don’t know why maybe the ID was not found of this reminder or something like something different failed otherwise uh we will say reminder deleted successfully so now I think we are completely done with our reminders service as well let’s check out the guide so yeah we’re completely done here so now what’s left for us is to learn uh well probably take a break and check out what’s happening okay react native me I went in art tried node media client but not work PC theme creator um not sure like we would need to kind of check out the exact errors and yeah it’s it would be a bit difficult to do now I’m a first time watching your video you can help me react native snap carousel snap carousels he right now it would be kind of difficult to explain but how to do them but maybe we’ll add them to one of our tutorials in the future and you could check it out but you can check also Chad GBT maybe ask uh how to do it and they will definitely give you a good example i’m Oh yeah the carousel yeah right now it’s going to be kind of tough to show it out i’m really sorry but uh yeah JBD can definitely show and I will try to actually improve it and not improve it but add it to to next tutorial so now we can go to the taskboard and check out the input validation and error handling this is okay looks like it’s a lot but it’s not going to be a lot maybe we’ll do it a little bit uh faster and um so yeah when building APIs input validation and actual correct error handling is very important because it’s it as I say here it ensures data integrity it provides clear user friendly error messages and that’s what we will try to do well first of all we will start with input validation and um it is important because when the user is trying to make a request but let’s say he sends an invalid data that might that might break our application and uh that’s a very bad thing because we want to make it so that our application functions as good as possible and without no breaking without anything so what is our goal is to ensure that the only the valid data that matches our schemas actually enters the system for that we will have implement input validation and we will use as I mentioned zod so you can go to their documentation and check it out but I will briefly like showcase you the most important part well first of all it’s very important to install it so let’s open once again our terminal we can stop the server for now run mpm install zod you you will see in here that it is added now we can rerun the server and um check out what’s next well first of all we will need to create the schemas and define them uh like add data types constraints and to ensure like basically tell our application what is an actually valid schema and what we should expect so for that let’s go to our source and create one more uh folder called uh schemas in here let’s create create a new reminder schema.js and in here let’s define the schemas so first of all you can just copy this one or and u yeah I will actually even go through it here so what we’re saying here is that the reminder schema object should have an ID of number it will have also a reminder which is going to be a string with at least one character and a maximum of 255 characters uh yeah I’m adding these constraints just to showcase you like different examples but you can check out like Z documentation and do them differently we will have also a string of notes which is going to be an optional so if it’s not provided it should this uh this basically z should not throw an error we’ll also have a completed boolean which is also an optional one and if it is not here it should default to false basically because yeah that’s it just created it should be false then it’s very important to have a user ID which is going to be a number and lastly it’s going to have a created ad field which is going to be a string and formatted as a date time so let’s copy this and just paste it inside our schema uh let’s save it but uh for now it’s not yet done because we need to define different this is our main basically object schema that we have in our database for these reminders and here I said uh yeah no so for these reminders so it has an ID reminder notes all of these fields basically but now we need to define a separate schemas for when we’re trying to create and when we’re trying to update so for creating we need to have like basically all of these fields except so what we’re doing here we’re taking this reminder schema the same as here basically referencing this and we’re omitting the values like ID so I we when we’re creating we don’t need to pass the ID we will create it ourselves completed is also you shouldn’t pass it because it’s also going to be always false by default and then created at it’s also don’t pass it because we will create it by ourselves basically the current date time so we’re going go back to our schema and paste this schema uh for create reminder schema now for the for the update it’s once again going to be very different even though like let’s say the reminder itself is here uh required when creating when updating it should be optional so you don’t really need to pass it so also notes you can pass null for notes if you’re trying to let’s say remove your note so it can be nullable and also optional but when you’re creating a note you cannot pass just null so yeah that’s that and lastly the completed is boolean and it’s also optional so if we go here we define it and now we have different schemas for updating and creating so if you go again to zod you can find different um like different uh how to say um functions maybe uh and um yeah read about it there is a lot of different uh validations like it but mainly this is the ones that you will use a lot and you can also ask for chajbt once again use AI when developing to build you uh schema with zod for example just say I will have reminders notes the reminder should be uh required it should have that and that length the you completed will be optional it’s going to be true or false or yes or no and will build you like this and you can use it so don’t forget to use AI okay now that we defined these schemas we need to create the middleware and as I talked already about middleares that will validate these schemas uh basically we will create a validation middleware and to do that we are going to create once again a new folder uh called middle wares and inside it let’s create a new middle and let me check how it should be called in order to have the same okay so yeah it’s going to be called validation middleware and uh let’s keep it nope js so this validation middleware will have uh this piece of code it looks a little bit intimidating let’s first of all just paste it in our validation middleware but I will go through it it’s not that difficult so even here I’m explaining what it does so first of all this middleware will receive uh in here the request response and next um like any express middleware we were always going to pass this request response and next to it this middleware will try to call the schema that we passed and parse it with the request body so basically with the in the schema that we defined are here basically and we will try to compare it in a to put it in a simple ways with the request body which is basically means with the input that user is providing that user is sending us it will try to compare with it and if everything is good it will call the next function which means proceed to the next middleware or route handler uh if it was not correct however we will go into a catch block that means somewhere we had an error and this catch block is not that difficult also to understand first of all we’re checking if the error is a zod error basically from the library that we installed and we as you see we here imported at the top so if the library is a zod error it means the request body did not match the schema that we were expecting so that means that we will try to build this error message in a human readable way so we are looping through the error that we received we are combining this message with different issues so here it might say uh like um reminders is required or something like this and then we’re returning the error with status 400 and saying that the data was invalid but if it was not a zod error that means something else failed i’m not sure what failed and then I will return simply u error status 500 and say that in it was an internal server error so yeah as easy as that now to apply this validation middleware it’s not that difficult either so what we can do remember this function actually let’s maybe close out a little bit of the things because we have a lot of them so the first thing it needs to enter is going to be the routes and we need to say okay so which routes uh are we adding this middleware well first of all let’s import the function that I just called uh validate uh date I think I called it uh validate data so yeah I need this function and I need to import it from it’s going to be from um middlewares/validation middleware so what we will do when we’re calling the create before calling this function we will add a validate data and we are also need to if you remember pass the schema to this validate data function so if you remember as well we created already these schemas so what what we can do here is say import and then we will import the name of the schema so in our we are create reminder schema we need the create schema and we will say imported from and let’s do schemas slash reminder schema and now we will say okay so validate data with this schema and if it’s correct because we are passing we are calling here next from express we will go next into and call this function otherwise if it catches an error here that the schema does not match it will throw an error we need to do the same for the update so let’s do that validate data but if you remember we created a different schema for updating because not all fields are required so we will pass here the update reminder schema but also we need to validate the data before doing anything else so as simple as that we are applying this these validations so here um yeah I’m saying what I suggested and uh what I’m doing and now if I go so let’s um let me think how is it better okay let me show you the let’s say when creating because reminder is uh required if I don’t send a reminder it will say invalid data error and the detail now is saying okay message reminder is required okay That’s very good like if I don’t pass the uh user uh I mean the notes and try to call it with and create it it’s going to work it’s not going to have any notes and completed is false but it’s working if I for example don’t pass the ID and try to create it it’s going to say that the user ID is also required so yeah that’s how it’s working it’s validating if it’s good it will go to the controller if it’s bad it will stop so here for example all of the fields are optional so in theory it will what the thing is checking for is for example if I pass some um actually yeah the thing is checking for because the reminder must have at least one character so for example if I have it like this it will still say that the reminder should be longer but if I pass at least one character and then send the update it will update the reminder to like what I wanted to so this is automatically helping us to like do so many things like catch so many errors and you could in theory even have here for the user ID to check it with the user ID that it would match at least one user ID in the user table you uh I will not show you right now because we’re like a bit short on time but just make sure that check out Chajbet and ask to show an example like that and you will see it and it’s going to be amazing uh it helps us a lot but now let’s see um okay past all this this as well let’s see how can we create custom errors because uh right now we are using throw new error just like you have let’s say in here I know not schemas but in service we’re throwing new error and saying some sort of an error well it has a few issues well first of all and the main one for us is that we cannot send a status uh code in a clean way so for example we cannot say that it was uh internal error for 400 or invalid data I mean 500 or invalid data 400 or it was not found 404 you could do it with this error but it would not be oneliner it would be a long here like at least three lives lines I think and repeating that would be also a nightmare all the time so we will create a custom error class for that and to do that simply inside the source let’s create our last folder called utils and in here we can add error message.js i think call it like this um oh no create custom error sorry my bad uh custom error.js and in here simply pass this code here so what this code does is we are creating a constructor our own class which will extend the error class that we already have here which is defined already but we will change it a little bit well first of all we will call um the parent class which is this one uh with the error message so basically we’re passing the message that bas uh here we provide here so it’s working the same it’s all good we need we can just override it but because we this error class does not have a status code we will call this and we’ll say the status code will be the status code that we provide in when we’re calling our custom error and we’ll see very soon how to provide that status code so before we jump in and right away implement our custom errors everywhere we can also see one weakness so for example here we have a lot of reminder not found reminder not found but what if I say make here mistake remander not found let’s say they’re not like they’re not consistent and later on if I would want to change the name uh for all of them that would be insanely difficult to go through all each of them and define a different error all the time so what a lot of companies are doing they create these constant static error messages and they reuse them that’s a very good practice of doing that it prevents the typos it keeps the code very clean consistent and later on you can even translate everything all of these very easily so it has a lot of pros let’s say to it so to do that actually I was lying not the last folder we will have constants and inside here for the constants we will create error messages so if we go here we say error messages.js JS and simply paste all of these messages that I provided you here we’ll have a few messages one of them is going to be reminder not found or we could have it even more general saying like item not found and here having item not found but let’s leave reminder not found you could have like user not found and more of that then we’ll have invalid data unauthorized forbidden and internal server error these are like one of the more common ones so now if we uh if we just uh use all of that oh yeah first of all yeah let’s uh start using these uh error messages and well first things first very clear one uh we need to adjust the newly created uh schema error where we throw these errors and make them use our constants that we just created so let’s import and let’s uh I already have here like um but okay I’m just going to show you in the code so what we’ll do is importing we are importing error messages from constant constants error messages and now instead of having this invalid data we’ll say error messages dot invalid data and here error messages dot internal server error now these will stay clean and if we any time in the future we want to change let’s say the internal ser error we can just go here and say try again or something like that and it will change to all of these so yeah very clean that’s the first change the second change is we will need to create this middleware to handle these errors because right now if we would have uh let’s say so let me go into one which one get reminder by ID and try to throw this custom error don’t forget to import it from here and let’s say let’s throw uh 404 not found and go to get by ID i think nine should be not found it’s still throwing us internal server error uh and not not found um yeah it’s still throwing us a wrong error well it is happening because we don’t have a middleware that would handle these errors so because if we go to our controller it knows that if something failed I will simply call this message with this message every time no matter what so we need to adjust that and in order to do that we will need to create this middleware so let’s go to our middlewares new file error handler middleware and then inside here we can specify this middleware what it’s doing is basically this error handler receives the error and it checks like okay does the error have a status code uh that we will pass if it has it will apply it if it doesn’t it will throw 500 then it will check okay does the error have a message if we provided it it will uh apply this message otherwise it will default to internal server error message and lastly we will simply as we do here in the controllers uh let me go here we’re sending the status with status code so status status code 500 404 and then we’re returning the error message uh very similarly to this like we have here so let’s copy this let’s go to error handler middleware paste this in and don’t we’re using already the error messages like um the created new ones uh so now that we are we created this middleware if you remember we need to apply this middleware and um but before that that’s actually very good that I checked the guide because even if we apply it we are never we are always calling this like every time um so it’s not good like even though if you are going to throw an error in here it’s always going to uh respond with status 500 and these error messages so what we need to do is go to the controller and if you already remember this next function and instead of calling right away this error we will say call next and we already uh saw this next and it means that call next middleware or yeah or router or whatever so we will basically express will call the next middleware in this case for us but now it’s still not going to work even though we changed it but because we need to uh so yeah now we’re passing the error and I actually forgot to pass the error itself so yeah you need to pass the okay the error to the middleware as well because if you remember let me show you in a second in here where we have this middleware we need to pass here the error and we it is expecting it so that’s what we’re doing here but now we need to apply this middleware so if you go uh well we’ll come back to these if you go to your index you need to add this middleware as the last one because if like as I said like it’s calling the next middleware so it’s going to call this one after the routes we are passing this uh new created middleware so if we go to our index and if we of course we need to import it here as you can see from the guide so let’s do that and we will say simply as the last one app dot use and use the error handler middleware just like we said to use the express.json middleware the same way we’re saying okay now use our custom one that we just created in here okay let’s save it so now that we have this we can go back and actually finally even we can test it with uh our get reminder by ID that we just created that uh where is it uh let me go to where is controller and get reminder by ID h get reminder by ID if no reminder throw custom error reminder not found and custom error where is it define where um did I forgot to export it c No no no it’s utils/custom error uh oh and we’re Yeah so um next is not defined i did not read that correctly so if I go here to our controllers uh we’re not importing this next so basically we’re calling it but we forgot to import it for every also a controller function so the this is what uh express returns like request uh response and also the next function so now that we have it for everything it will now display the error but the error will be this one it’s not standardized yet so if I go here call it it says reminder not found and not capital letters doesn’t look very good so let’s adjust it and make it perfect so error messages dot uh and it’s um reminder not found so if you can see error messages are important from constants so now if we call it it will have reminder not found but it will call it from this so we can say maybe even item not found to just show you that it actually works like this so if I save it and go of course now I need to adjust the name uh in this service because there’s no reminder not found now it’s called item not found so if I send it it says item not found that means it’s using that and it’s perfect so now in this file everywhere where we using the old error we will change it to a custom error and let’s say error messages dot item not found and it’s going to be 404 so here as well like reminder not found we will call the same one these are different so I’m not going to change them just yet and is there any u an any other errors throw error uh so yeah there’s you’re not on you’re not authorized error so let’s adjust this also so it’s going to be forbidden and forbidden I think it’s 400 no 403 is forbidden so okay forbidden you see and I don’t remember them by heart and the last one is something like fail to delete a reminder so we are simply going to check like uh throw uh internal server error which is going to be 500 so let’s save it and now I think there’s no throw new error so now all of the errors are going to be amazing uh so let’s for example let’s try to uh do update 500 uh could not determine data type of parameter 2 um this is a weird one so if it’s 10 uh bind message supplies two parameters but prepared statement it requires so it is some let me check it out that’s actually interesting so if we go to update reminder so we had these new values is not let’s try to console log our query real quick and if we go here if we try to call this what does it uh Okay so we’re saying where ID Oh okay so that’s actually that was my mistake we don’t need to take it from at which position we actually need to take it values.length so the ID is going to be at the last position always so my brain is a bit fried for us it’s already almost 10 so give me some slack but yes here we wanted to say like where the ID is not like equals the actual value of the ID what we were doing before because this one is actually let’s show it as an example that’s a very good thing that we caught it so if we have it like this and then I would leave it only like this and now if I would call this here we are saying okay okay but the ID is the same so maybe I want to do like this 100 so now what we’re saying is that okay so uh set this this reminder where the ID is at position 100 but we’re not even passing that many values here we only have one value and we’re saying at position 100 so this is what that does that’s why we need to keep it only uh values.length because in theory uh we are trying to update uh where the position is and it’s not minus one it shouldn’t be minus one it should be normal one so if we do this one and again console log it so now we’re saying yeah like at position two because we have at position one we have the reminder itself that we’re passing here and at position two because we added it with values push and push adds at the end of the array uh we added the reminder ID so the reminder ID is always going to be the last uh item inside the values array that’s how you a access it by saying values.length length give me basically if the length is two it’s going to be at position two so yeah this is that’s why I said like it it’s weird that we I’m doing this but it was my my bad so now it’s working and we’re saying that item is was not found perfect so if we go to our guide how does Yeah so service handles business and throw structure mhm so here I you can see how everything ties together so basically what we are doing is first of all we are calling the validate data create reminder schema so if we go to our routes here that’s what we are calling if it doesn’t have it it just skips this and right away goes into the controller but if it does have it’s calling the valid data with the schema to validate it and only calls the controller if the schema is correct so that’s what we just checked then controllers call services so if we go to the controller the controller will call the service in here and then this service is going to process the data and do whatever but if the error occurs while processing the let’s say the data like here we we weren’t able to find it will throw this error then what happens is that this error is passed to the error handler middleware via next error so for example if we go back to our controller because an error happened here we’re catching it and we’re passing this error that we threw to the next which is error handler middleware because if we go here the next one is error handler middleware so then uh service uh yeah processes the logic and throw that that error that I just talked to you and then return error handler middleware returns a structured error with a status code and with a message or with a defaulted values so that’s how everything ties in together um so just try to experiment this will make sense if you try to sometimes when you try to do it only once it might be a bit confusing but this is I know how like also started just try to do it once twice and then later you are kind of um tie everything up in your head as well because you forget to add something and then okay you see oh it doesn’t work why it doesn’t work then you say oh I forgot to add maybe this middleware or maybe I forgot to tell the our app to use this middle middleware that I created so it and also if you while watching this have any questions uh feel free to leave it under the video it’s this video will be up and also feel free to ask JBT it will always answer at least give you an idea of the answer but if it’s not clear enough leave us a comment and I’m trying my best to always go back to the videos at least for the first few months and try to reply to you so yes that is actually how we implement and how we properly structure our API our backend and how most of the big companies are structuring it if you come to a job uh interview as a junior or maybe even as an intern knowing all of this will help you a lot and you will even if you don’t have everything like down to a tea how it’s said uh you can already have a good idea of uh okay I remember I saw this I remember it can be here and I remember more or less what models are doing so you can get a gist of where you add your logic where you add your database and how everything ties up it it ties it together basically okay so now that we’re done with our back end it’s time to do the front end the front end is not it’s going to be a very easy one so again I’m not going to spend too much time on it we have a lot of tutorials on this channel uh how to implement it with way bigger examples way more difficult examples this is going to be a very very small uh application i’m seeing that it’s already almost 4 hours so as always uh it’s not going to be a short one but um yeah hopefully it’s going to be a good one so first of all what we need to do for the to create our uh our let’s say mobile application expo application is once again install NodeJS but if you you are 100% have it installed because if you wanted to follow the back end you needed it as well then if you are running it on a physical device you simply need expo go application that you can download on your um device either Android or iOS from the app store and you’ll be able to run the application without any extra setup just like that however if you want to run the application on a simulator on an emulator on your machine you would need some extra setup and here I am providing this setup like you can follow the documentation and um run it uh but for this guide I would suggest you if you are just starting out do not even bother with all of these just check out uh using um Expo Go application it will work just the same and uh if you feel that oh okay I’m liking uh React Native Expo it’s amazing then you can set it up everything here as well again a few things in mind uh Android is available on all operating systems but Xcode which is required for uh iOS simulator is only available for Mac OS however you are still able to publish um iOS applications to the app store uh using EAS but uh again this is not what we’re going to cover it it’s like a next next step uh it’s a lot of theory so maybe we’ll do a tutorial on how to do that but we’ll see so yeah as I said right now let’s use Expo Go i will use a simulator but just because I want to show you the screen of the simulator on on the live stream that I’m doing now so once you’re done with the configuring let’s set up a fresh expo project and it is actually insanely easy just copy this line of code go to your terminal and run this code so what we’re doing here we’re calling create expo app with the latest version we’re saying this is going to be the name of like my folder in my application and we’re saying d- template and it is because um by default here if you don’t provide a template it will create a default template which will already include some tools and which you will probably use for most of the your apps but because I want to show you everything from scratch without having anything else pre-installed we will choose the blank TypeScript So let’s choose that and click enter now while it while it’s installing let’s go back and check out what’s going to happen yes probably you will not see this uh unless you started with the with the Apple like the front end first so if you see this just click yes I trust the authors because you are the author you created everything and now we will need to open another um VS code um project in VS code so to do that what we will do go to your Xcode and you can simply uh either go um file and maybe even new window or I’ve never done it yeah new window works but you can also click commandshiftn uh if you’re on a MacBook or control shiftn if you are on a windows and it will open you with a shortcut this new window so now that you opened it go to files uh and in which I I think I have done a little bit of a mistake because I created this uh Apple reminders clone inside the Apple reminders API folder so if you go here uh we will already see this I will remind us clone so do not do not do that that’s uh we needed to do it in a different folder so yeah I will simply delete it from here if you follow do it like that that’s not an issue and now if you see that you are in your API folder just simply do cd and then double dot that means go one directory back and now I see that I’m in the right uh project directory so now I can actually run this command and create the project that I wanted with a typescript and um yeah now we are going to wait a second it created it so now we can go to our VS code on file open recent uh or no actually open and then we are going to go to uh documents projects and here we should have apple reminders clone let’s open this project and now actually that we’re not going to use the reminders API that much anymore so let’s do it like this okay so now what we need to do is run our front end application to do that click on terminal new terminal and in here simply write mpx and I see that I need to increase it maybe not sure how much um but yeah maybe that’s enough maybe that’s better we can close this clo uh welcome mpx uh expo start once you run this you will see something like this so if you’re using Go if you’re using Expo Go simply scan this QR code and you will right away see the application on your phone just as easy as that no setup nothing for me as I mentioned I will be working with a simulator just to show it uh on the screen so uh I pressed uh Y to open iOS simulator let’s minimize this screen a little bit to fit in the emulator as well so if I go here I know that some of the emulator is hidden behind my camera let me fix that real quick how much something like this probably should be good maybe a bit i can use a bit more and then I can extend this until the end perfect so now that we have our app running we can see uh here open up app tsx and start working on your app so if you go here we can change here the text to anything something like hello world and if we save it we already see the changes that means everything is working everything is set up correctly we can continue working so actually now this is not in the place anymore again okay so yeah here I explain all of that and now let’s create a basic structure once again so just as uh like we did in the API let’s create a new folder in the root directory called source here we will keep all of our source code basically everything that we create inside here the two folders that you will always create especially if you’re using export router is going to be app and also inside we will create components component yes so here we will keep all of our screens uh and we will talk about it soon and here we will keep like Lego pieces small components that we will be attaching in our code so as we can as I said here for screens and navigation app and for components for reusable UI components little Lego pieces now another very important thing is to set up uh path aliases previously I wasn’t that big on them but um because I didn’t want it to overwhelm beginners but they’re actually amazing and without them the project can get a little bit unclear because this is by default how would you import you need so many like go back go back go back and then one directory back one directory back then components and list item if you have path aliases set up you can simply say like this you see how much cleaner it is and to do that the only thing you need to do is actually in the TS config which we have here you can just add this line like we don’t we’re not going to use assets now but so you can only add this but basically only this small part if you add it here uh yeah here you will already set up these path aliases and when I’m let’s say here I’m saying go to at and then component so what it’s saying this at because we’re here specifying uh at and it will be inside the source basically go source components or I could say uh at app or whatever so this is setting up the path aliases and it makes it a lot a lot more cleaner now we can import it just like that perfect we have the setup done now it’s time to implement the expo router and the navigation but before that let me maybe check out the um the chat and Lucas is low-key killing it thank you Catalyn thank you always here always supporting um link lend my error runtime not ready cannot read property style of un undefined probably you didn’t define the style somewhere you’re trying to access it but it’s either not in the right scope so you defined it in the wrong place or it’s like not defined at all uh music forever love you thank you thank you very much uh I appreciate you you’re here actually I remember in Apple News Clone you were here from the start until now you’re here today so I really appreciate the support and I see Reelio is also here still thank you thank you guys very much you’re you’re an amazing support guys always here always supporting huge huge thank you so let me actually take a few sips of water it’s important to stay hydrated oh that was a good sip of water but I like I almost don’t have any left so let me uh Okay um so we’ll be installing now the Expo router for our navigation as mentioned so to do that just go to the official documentation which you can find at um yeah this link or just go to the notion guide that I provided now we can close these because we will no longer need them and we will follow the installation so first of all we need to install all of these dependencies and actual exper itself so let’s do that open the terminal you can do it with terminal new terminal or with a shortcut let’s stop the server with Ctrl C because we will need to rerun it with a clear cache and now we can paste that long code but I see that I included some not necessary symbols like 200 um yeah that’s a long way i could have done it shorter but yeah let’s install all of these libraries they will appear here inside yeah here all of them are installed now what we need to do is we need to change our main entry point in the package.json so let’s copy this and go to the package.json we’re already here and inside here where it says main and right now it’s index j index.ts TS which is here we need to say okay we will change it and now we will uh use the export router entry which is going to be the app folder in a way we’ll see it how it works a bit later then we also need to for deep linking which we will not really explore and but it’s not very difficult we will add our scheme so in the app config which is app.json JSON i like to do it under the slug here add our scheme so let’s say not just uh reminders something like this uh actually like this not just reminders um or even not follow it completely like something like this not just reminders okay now that we added this scheme we could install React Native web and React DOM if we want to have our application also on uh the web right away and it’s just like installing this and that’s it just to save time we’re not going to do it uh but yeah it’s very easy then you will need to also enable the web bundler and then you need to modify the Babel config if you have it already changed by to use basically Babel Babel preset expo but uh by default this is what Expo will use so you will not even have this folder this file in your file structure because this is the default setup for it so the last thing we need to do is we need to run our server again with clear flag that means clear the um clear the cache so now if we run it and open it reload we will see a little bit of an error saying that expo cannot find the routes any like inside the source app directory and we changed that the main entry right now is inside source app so let’s create a entry file called index o not js I am used right now from um tsx yes and now let’s define our let’s say entry file it’s not going to be right now anything too crazy but uh we will have something like export default uh function we will call it home screen because this is going to be our home screen and we will uh return for now simply a view let’s make sure that you import the view from React Native and we will also import text and also make sure that you import it from React Native and in here let’s say hello if we save it we once again hilo hello once we can see it here that means it’s working the expert router recognizes our routes everything is perfect so now that we are no longer using this apps and this index.ts ts we can safely remove these files and nothing will crash nothing will be bad uh because now we our entry file is the index so uh we can also close this and go back to our uh notion guide what we did we installed we created our first screen so now uh let’s see uh should I um let me think like because we will sh okay so I will show you the navigation a bit later on how you can navigate but if you’re following this uh notion guide feel free to just like follow it and um here follow these examples but I don’t want to waste your time at my time right now uh mine is not that important yours is very important important so I’m not I don’t want to waste your time and go through these um little examples that we will later like very soon actually remove and we’ll also still see how the navigation works so you can read and implement but if you don’t want uh let’s just continue so now this is an important one and um the lay let’s a little bit talk about this layouts file this layout file uh is like kind of like a wrapper uh around your screens because by default all of the routes fill the entire screen so this basically is a route and it fills the whole screen but sometimes uh so yeah and if you would move to another screen this will change the full screen everything inside it will change but sometimes you want to um keep some of the things for example the headers so you would want to keep here the header or you would want to keep the bottom tabs as your navigation so in order to keep those things we need this layout that will wrap the screen so it will wrap the screen and it will put uh it will yeah this is going to be the layout and here you would have your screen that you created basically inside it so you would still see everything that you defined inside the layout and also uh what you have inside the screen so in order to think of the um in order to showcase how it works we can create this layout file and let’s create it inside the app and let’s make it layout tsx um so now that we created this layout file in here it’s actually uh let’s export default function and also let’s call it root layout and why we call it root layout it’s because it’s in the root basically the main layout inside the app this is going to wrap everything that you add all of your screens inside here it will wrap this is going to be on top of them so root layout and in here in here let’s return and let’s return a slot from uh actually not a slot stack will be a better example let’s return a stack from I didn’t close sorry didn’t close the tag from react uh expert router and right away after I save you can see this header and this is what stack provides so uh with stack you will have the all the u go back like for example if I would navigate to another screen here it will automatically add go back arrow and it will it will always display the headers we can hide them and I will show you how but this is basically what’s wrapping all the screens in here so actually I kind of have to show you this example but if you add another one let’s say about tsx and uh let’s say about screen and then let’s say here about screen so now if we have the two of these screens and I go here and say link link and then here we say href and I say go to about screen if I click on it you can see that it right away went to this new screen that I just created but because they are both under this layout they both have this header uh because I said this layout wraps around everything that you add inside this app um app directory so now if I and it also added this back so it has also the stack keeps the history of where you went so if I go back I will go to index now there is also a slot but the slot will not return anything basically it will just render the children inside here behind hiding you can see hello from here and if I yeah you like let me add uh here style and some margin top like 50 so here you can see this hello if I click on it we went to about screen but I cannot go back it did not keep this u history so yeah that’s why we will use here the stack for us and we can remove this delete i said I won’t waste your time but I did so yeah this is how you can think about layout and in our let’s say Apple News clone or a Reddit clone that we did recently uh I’m sure Vim also in his clones um use the layout even more like nested layouts because you can have a layout inside a layout this is a bit more complicated so let you can leave it for your next tutorial okay so now uh there’s a quick guide like how uh expert router decides which screen to load basically because you saw here we had two screens but how did it decided to load the index and not about and here um like I can you can read a bit but the basic rule is that expert router will look for the first available index uh file in the project directory and it will once it finds it it loads it right way if it doesn’t find it let’s say at the root level if I had here like something like protect oh not capital protected and I had the index inside here so I can even actually not create here but move it so here inside protected and if I reload you can see that it’s still here like but now the index inside is inside protected and index so it’s looking for the first index that to find and it goes deep deep deep searching for it so here’s a short step-by-step like um explanation of how it finds it uh and here’s a very common also way example of having two subfolders which is going to be protected and O protected will contain all screens that require authentication authentication and they should not be accessed uh any other way and O will hold all of the screens like login register forgot password basically the screens that can be accessed by unauthenticated users so first of all the root layout loads app.layout uh because this is the first thing to be loaded always in every so for example I could even create here another layout and uh in that case uh let me showcase what will happen so if I do this and this will be let’s say protected layout so now it has two headers because the first thing it always does it loads this layout it doesn’t find in the app index it goes into folder in the further it finds here an index but it still loads the layout first so let me move the index out of here because we will no longer need this but let me go through the example so yeah it loads the root layout it it finds there either slot or stack which again acts as a wrapper since there is no index inside the app uh expert router will move into subcategories so expert router will scan those subcategories in order that they appear in the file system so for example this or here if we had like as I said another file something like um I’m not sure like blog blog.tsx it will look them one by one like this so basically alphabetically because this is how they are ordered here in inside so the first valid index found we determine the initial screen since the app has no index it moves deeper in the subcategories uh in the subdirectories and scans them also in the alphabetical order so for example if I had here O and protected it will go into O first and then in protected because it didn’t found any like index in the O it will move next which it will find the index inside protected and immediately load it like even if protected didn’t have an index the expert router would search even deeper and a very common pattern as I say here is to create a tabs folder inside protected and then in this case expo router would continue searching inside tabs and even deeper until it finds the index there so here I’m also specifying what will happen if the off and protected had an index and basically to summarize it it will uh load the o index if you don’t have any layout checks there because you can add any code here to be executed in the layout before even loading here so saying like if uh not o basically if you don’t have o uh then we can uh redirect to somewhere like if you don’t have this in the o uh layout it will load the o index because it found it there first be uh so here yeah here because it’s alphabetically uh so yeah that’s that’s the main gist and we have these these examples in Apple um Apple News clone and Reddit clone and pro Vadim has in other uh projects as well so here if you want you can always go back and check the final code of our root layout uh but we will implement it step by step so let’s go we implemented the expert router let’s check out the tanstack query and why we would use that so TensaQuery is a very powerful tool for state management uh and also like for fetching uh it simplifies it caching fetching synchronizing updating the state so basically instead of handling everything manually it helps us to do it basically with a tanstack query so this is how our request would look like without timestack query we would need to handle the loading we would need to store our reminders when we get them from the fetch request to the state as well we would need to also handle the error separately and set it catch it and finally set the loading to false and here actually it should have been at the start like set it to the loading to oh it’s initially true and then you need to call the fetch reminders and use effect this is a lot of boilerplate for one fetch request so look how much it simplifies everything if we’re using the tanstack query so this is only one advantage of it but also it has global caching so tense query like caches those responses automatically which means that if the same request is made like in multiple components it will be dd duplicated avoiding like unnecessary network calls for every time that you do a request so it keeps that data cached fetched by refreshing in the background and it handles like garbage collection of all data and basically optimizes everything it’s so so good so it’s um to do to use it it’s very easy setup first of all let’s install it with npx expo install so let’s open our terminal we can stop the server once again and I again got this 200 so let’s install tack query and once installed inside the app layout basically the first uh the first file that will be loaded we need to import the query client and define it so if we go to the layout here uh what we will do here is we will import this layout client and let me check if the stream is um yeah okay it’s good so uh we will import the query client and also provider we’ll see later what we do with that we are defining this new query client and then we need to wrap our whole layout with this um query client provider and then pass the client there so it will look something like this so if we keep it here we’re wrapping our whole application because if you remember the layout will be loaded first this is the root layout it’s nothing is going to be above it we are um we’re uh wrapping everything in query client provider and we’re passing this client to it to know like okay basically which client to use now that it’s done uh here you can find the final code but we’ll check out how to do it that’s it you can start using uh sorry you can start using the tanstack query just like that so if we go to our first component how to do that well we already used some components like text and view and they’re react native built-in components and we use them inside here inside our index like view and previously you saw text link is also built-in component from expert router but we can also create our own components so to do that let’s start seeing how everything evolves and basically how everything ties up so first of all let’s start u by displaying the a simple reminder but in order to display that reminder well we kind of need to query it from our uh API that we just created well let’s do just that let’s go to our code inside the index well first of all let’s start the application once we have it ready let’s open it on iOS let’s say reload with by clicking R and then yeah and then let’s start working on it first of all we need to do the query as I said well in order to do that it’s very easy first of all we will define that u or maybe let’s start with use query from tanstack query so we’re basically going to use this fetching and inside here what we need to do is we need to pass a few things well the first thing is the query key and the query key is there to know basically for caching like and you’ll see later on when we add a new um add a new uh record to update the lists and u actually now that I’m thinking I will expand this um after the stream probably tomorrow it’s going to be too late today but uh expand this uh guide and explain a a little bit more inside the tens query um lesson what is the query key and what is the next one that we will use which is query function well query function is kind of um self-explanatory we will run the function um that we will define here basically what this query your query needs to fetch or whatever so in theory what we could do is we could simply uh inside here define like right away uh fetch uh first of all we would say const response and equals now here we need to define like what we are fetching like the URL so we will say await that’s very important we will use the fetch uh function you could use axios or yeah it’s up to you but we will say uh await and it’s going to re a bit complain about the weight but we’ll fix it later and now what we need to do is we need to get our URL the same way as we were doing inside insomnia so for example let’s we’re trying to get all reminders so let’s copy this go back to our code and let’s say okay let’s call uh this basically function and what we need to do is we need to get the response and yeah this response should be parsed to JSON and we can do con um actually we can return it right away so yeah this is what we will do and here you would more time like all the time actually you would have an error catcher so for example here would say if the error is the if the response is not is not okay like the it’s not 200 then something fails so we would say throw uh new error and it depends like now it’s also based on how your team is handling you can define here your own like names fail to fetch a reminder or reminders actually it’s plural or you could reuse the error messages from the like back end that we’re returning so it’s really up to you and um yeah I will show you this way so yeah uh but this like reusing this and maybe you will need even to call this same query somewhere else in your app for example if you have different lists or whatever well there’s a better way once again to handling this and the better way is creating a services folder inside source and inside this services we will provi provide create reminders or maybe reminder service.ts and in here we can like create all of these different functions that will have all of the logic and that we’ll be able to reuse very similar to how we did like we use services in our API so now let’s define actually the first service and the first service function it’s going to be export a sync that’s very important because we this function will be a synchronous we will need to await something to re return so a sync function the name it will be get reminders for now it will have no um no parameters and in here what we will need to do is simply call all of this so we can copy it and paste it uh too much a bit so now we can reuse this get reminders function everywhere in our app just like this and it cleans up the query function here a lot a lot more so what we would do is we would say get uh reminders and make sure it’s important from services here from services reminder service uh get reminders and then we also need to say um okay something here I made a little mistake um oh yeah not little actually a huge mistake but why I removed all of that I don’t know because we only needed to remove this this part and also we don’t need this little part but we need the closing tag and um yeah and this part we also need so here we can move them here and here we will say get uh we will use the oh get reminders from services reminder service let’s fix it a little bit and also we need to call this function so now uh okay it says is yeah so now we will get a little bit of um of an error but it’s not uh because we’re not done with how we are basically defining all of this when uh this get reminders are is called what we need to do is we need to destructure from this use query a few things and we already learned about the structuring so basically what this returns to us so it will return data it will also return is loading so basically data is already what is going to be returned from here so in this case the response JSON the is loading is going to be true while we’re fetching and once we get it will be false so that’s how we control it very easily and then we will also see an error here so now um now we can let’s do it this way yeah what uh why it turned white it says no query client set use query client provider to set one but do we actually have one from tense oh we did not save it after changes so now yeah I I saw a little bubble it was not saved sorry my bad but now that we saved it’s working so now if we go to our uh reminders and if we console log the data here uh let’s go here we can see that we are receiving this data we receiving one completed false created at id notes and reminder by milk we remember that we created this here we are also receiving the reminder uh of one we also remember that we created with it with notes don’t forget to feed him for so we’re we’re already receiving the data from our own API and in order to see that it’s actually from our own API we can go to the controllers reminder controllers and for example for all reminders we can console log saying uh calling this function so if we save it now once once we reload this application sorry once we reload this application if we go to here uh oh we are returning we’re console logging the reminders it’s going to be a little bit messy so let’s do it once again so now if we go here oh what are we console logging still here but we see that yeah calling this function is here uh so that means we are actually going inside here going inside the get all reminders well first of all starting of course from routes getting inside here our model is calling the database with this exact um let’s say query and it returns us back so here was what we’re console logging and it returns us back to controller the reminder says a JSON with status 200 which means everything worked perfectly amazing now that we have this data we still need to handle a few use cases for example if we are loading uh if if we’re still fetching let’s return an activity indicator for users to understand that uh activity indicator from React Native from for users to understand that okay it’s still loading so be patient uh it will be the data will be the list will be here soon let’s add some margin on uh top to see it better like something like 20% uh oh sorry like this let’s save it so now you saw like a short loading period so if I make it like is not loading you see here is g how it’s going to look like you can also pass I forgot like yeah size and you can say it should be large so now the loading is big okay perfect now we also need so for example let’s simulate an error let’s say if response is okay throw an error so now it’s not going to show us anything uh else because what we need to do is we will add yeah here the loading was a bit longer because again a very good thing about uh tens query it’s retrying every time to call again because oftent times um calling the back end again uh is fixing the function you see how many times it called our API and often times this is should be enough like because it it can let’s say at least it can fix the issue by calling it again so we don’t need to set up anything manually it’s right away trying to provide a good response that’s amazing another very cool thing about um about um test query but let’s say if we had an error we need to return this error so in order to return this error let’s define how it should look like so we’ll not do anything too crazy we’ll simply say we render a text and inside here we will uh of course opening this so we’re saying okay don’t we’re not adding just the text but the JavaScript expression and we will say render the error and the message that you return from this error of course we will probably need to add some also styles like here it doesn’t need to be too pretty so now if we load it and actually it’s not going to Yeah let’s wait now here we see failed to fetch reminders so that means that um this this service threw an error and um the utens caught it and returned it to us so now we can display the error message which is failed to fetch the reminders we can also make this a little bit maybe nicer something like bold or not font size font font weight bold and then yeah maybe justify content should we align no align self i think it’s align self center and now it will look a little bit better let’s structure it like this as well yeah I’m spending too much time on this error of course but I cannot leave too bad of a quality okay so now it’s good so we can say if the response was not okay then return me this error otherwise the data should be there so now when the data is there we can start working with it well first of all we already remember this kind of syntax so let’s do that here underneath like if there’s no errors nothing else let’s take uh the data at position zero so basically because if you remember it returns us an array here you can see it returns us an array of objects so we will take the first one inside an array because zero is first and now we can start working and implementing this um slowly this custom component so first of all we will say okay so inside a view we will have a text and the text will say reminder item um I’m seeing some messages um okay uh reminder items and then we will say uh yeah reminder because that’s what we receive we also get the notes so if we save it we can here see buy milk if we say give me at position one it’s going to be one with don’t forget eggs i don’t think if oh we have also at position three so take the dog out for a walk don’t forget to feed him before so this is how we’re already using the data from our database but um imagine if we would need to uh create all of these separately so for example I would need to have another one reminder item two um and saying like something like this this would be a little bit insane first of all and uh not very maintainable second of all and here yeah I’m again saying why we use curly braces because JSX treats everything inside text as a plain default text but in to include dynamic values like here we need to wrap them in a curly brace to tell that it need to be evaluated as a JavaScript expression so to make this a little bit more reusable inside a component let’s create that Lego piece that I was talking about with you let’s call it reminder list item tsx and in here um yeah in here we can uh move all of this logic so that we had here with uh displaying notes and reminders to here so let’s do export default function let’s call it reminder list item and let’s do it return and let’s return something like uh view and also a text we need to import it so you can import it by pressing command Y and make sure that it’s imported command I yeah command I and make sure it’s imported from React Native uh and do the same here and make sure it’s imported from React Native or you can just write it yourself like this so here we also can do the same thing by basically display display some text let’s say here we will be reminder uh and let’s leave it like that for now so now instead of creating this huge code and imagine if there is more styles more text it would be very bad what we can do is we can simply let’s remove the link import this newly created reminder list item from components reminder list item and inside here we can simply use it like that reminder list item so now we’re using this little Lego piece inside our code and u and basically we are able to reuse it and we can use it anywhere in our app like anywhere at all that’s very good but now we’re displaying some random information how do we display the actual information that we need well the same as we were passing props here uh parameters we can pass it to our components so for example we could here say that we want to receive reminder item and now we define what is that reminder item for us it’s going to be let’s say this one and we can even do a second one and yeah do reminder item two uh so now if we save it and now we can see that it displays two but how can we take the data in here and reuse it well it’s kind of not too difficult in here what we will do is we will take the name here reminder item we will destructure it right away to reminder item otherwise you would take it as a props and then you would here do props dot reminder item but we already learned how destruction works we know how cool it is so let why not use that okay we have reminder item now we can start using it so for example if I say reminder item reminder and even reminder item do notes if we save it we are right away seeing the data the actual data that we need which is amazing of course we do see some red warnings saying that it has an any type and TypeScript is not happy about it at all but we will fix it very very soon so now if we go here uh yeah I’m telling that this is how we made it manageable reusable and very scalable i told you how to pass the props and actually yeah like if you would go here and say I can pass hello again hilo hello equals let’s say something like hey we could get this data inside there as well so I would say how I named it so if I go here I called the prop hello so I would go no no no no not full I would here also say hello and now I could simply uh display that instead of what I was displaying before but what I need to do is I also need to pass it here because otherwise it will crash so if I save it here I save it here we’re displaying the hey so we’re displaying the value that we passed which is here this little thing so you can pass as many parameters as you want and it’s going to work you can use them here u the way you need it to be and we’ll see a bit later but for now what we need is the reminder item and display the notes and the reminder itself so yeah we saw how to pass the data uh how to receive the data and how to use it here I’m also like giving you a little bit of an example of uh how it will would you use it if you wouldn’t destructure it here so you could have here props but then do props render item reminder but now that we structure we can do reminder item reminder let’s close the service for now and let’s close uh the let’s let’s make this a bit smaller we don’t need the layout the index will need app don’t need don’t need don’t need so now we can start working on the designs and I have provided you here the final code of the design how everything will look like so if you want just go there copy it and u yeah and you’ll have everything ready but we can do it uh real quick because it’s not that difficult ourselves well first of all we will u have our reminder as untouchable opacity which means it’s going to be pressable so we need to of course pass the on press function to tell what will happen after user presses on it so we’ll say console log and we have pressed amazing that’s very good but we can also pass some styles to it so if we save it now you can see that it’s pressable if I press it’s doing like this little animation but um we need to pass some styles to this whole component because now it looks well to say the least horrible so these styles can be first of all we need to um yeah oh I forgot a bit more i don’t have a design on my on my screen so but if you want actually and I will do that i will uh go here and here I will move it to check the design and it will be a lot easier for me okay so yeah I can see right away that we need to have um little icon beside it and um and then another icon at the end of it so actually without showing to you it’s also not going to be very good good so but here as you can see we have this little button to know if it’s already um completed or not we have a more information button and we have some text here so let’s start doing like from left to the right what we need to add is the the icon so I already have this icon ready and let me copy it so it’s going to be here let’s save it and also uh to use this icon we need to import them from material community icons and we will also need the undesigned later so now okay we have this button perfect that’s very good we also need the uh other button that I talked about which is the um which is the the the information button that’s that’s how you call it probably so let’s do it that way u okay like this let’s save it and we already have some styles to it so we are aligning it at the start like maybe I will remove the styles for now okay so now we have all of them like that well what we we see is that they should be in a row to achieve that that already gives us a very good hint because we want them to be in a row so flex direction row now we have all of that in a row however we don’t want these two to be in a row we want them to be as one component so to achieve that we are simply going to wrap them inside one view and now they will stay under each other but this uh this and this will be a line in a row so that’s already achieves a lot if we would add this for example inside here it’s also going to stay in a column but we want this to be at the end in a row perfect we have this we also want to align all of these items inside like and center them like this for now later we’ll change this but we want them to be centered also we want them to have a gap between each other something like like a small gap between here and here now um now that we have this I’m thinking um what would be the most important part for the Yeah so let’s say we also want this uh information button to be aligned like completely on the right to achieve that we will have margin left and we would have auto amazing that’s that’s what we wanted to do we also it’s a bit too close to the side so we will have margin uh right and we will have like something like five having it a bit uh more outside of the wall okay that’s very good so now the worst thing that like for me here is the text it’s too small it’s um like hard to understand which is reminder what is note so let’s maybe quickly style them it’s not going to be too difficult so let’s do that for the title uh of the reminder we actually don’t need to pass anything maybe if you want to make it bigger maybe we’ll do that for but for the uh notes we definitely see that it is a bit smaller so maybe something like 12 and we see that the color is gray but not and not black so yeah maybe uh I will make it um yeah for now let’s leave it like this may if you want you can do it bigger but now I also want to have a little bit of gap between here and on the bottom so again it’s already saying you what we want to add which is gap and the gap could be of five um but now let’s say that the reminder can be very long uh even longer even longer and now it pushes like our icons out what we need to say is that the flex box that it is in should so basically if everything something that’s inside here is moving out of the flex box that it’s in and you can see the flex box that it’s in by doing background red then move this everything inside like for example if I move remove this you can see that it’s going out and the the flexbox is actually here so I need to do um background blue but you don’t see it because of this but yeah basically what it says is if something is going outside of the flex box please uh don’t do that so we uh can achieve this now what else well uh let’s see the designs well they need to have some sort of uh like more padding around it and like the lines uh under so that means we will be continuing continuing to add styles to the main um main component that wraps everything so first of all I really want to add some margin between them all of them so I will say margin bottom and it should be quite a big margin from example like this and I also want them to be a little bit um separated by a line so to do that we can very easily add a line border bottom width and we can import we can even either say like the width should be 0.5 and then we can say border bottom color and the color will be in our case I see gray or we can from the stylesheet that’s imported from react native very important we can get the hairline line width which makes it a little bit smaller and look better in my opinion so now that we have all of these uh I will I still want to because this line is too close to the to the note let me add some padding uh on the bottom and here we say let something do like five or something like that so now we are kind of moving towards um what we want of course uh here you don’t see the final version it’s too close to the sides but we’ll get to that right now we’re only wanting to solve this and actually here we can move back to reminder item reminder okay so now we have these uh what we want to do next let me check the design so here we kind of are okay yeah here I see that the this icon is not very well aligned so we need to align it with the title here at the top but now it’s in the middle between these two so what I would do here is I would say align uh yourself so align self and align it at the start of the flex box that you are in so it moved it to the top so now it’s kind of um where we want to be not exactly but we will um solve it a little bit later inside the index when we are be applying the styles there okay but now this u button is always pressed how can we control what to dis how it should be displayed well for that I decided that we will use uh state so to use a state what we need to do is first of all dis uh define the variable name a set is comp completed so we need to define the variable name and also say that okay it is going to be a state by calling as a use state from react and it should usually be the first one um a hook so what is a state a state is um do I have an example no I didn’t so basically a state is a variable uh that once it is changed the whole component is rerendered and we’ve talked quite in detailed in Apple News clone about it so if you want check it out maybe only that part but basically what it will do once we change it it will go through everything and adjust it basically or rerender your whole comp whole component to show maybe some changes that we will do right now very soon so again we can define inside the state a default value basically how it is going to be initialized and if you remember our reminder item has a completed field which is basically specifying if the item if the reminder is completed or not but now we still always displaying this completed button well that means we will need to uh render the icon conditionally so if it is completed we will show one thing if it’s not we will show another so here we’ll say if it is completed let’s show what we are actually showing here let’s maybe clean it up a little bit and here like this and here like this okay so now here we Yeah if it is completed we will show this else this little double dot mean else else we will show a little bit of a different icon and I have it here so let me copy paste it um else we will show it incomplete so now it’s a lot closer to what we need to have but now how can we make it completed well actually we will do it by later on calling a mutation but for now what we can do is say set is completed and make it um so the right way would be to take the current state and say make it different so if it is now completed it should not be completed and vice versa so now if I save it I can see that it’s being applied to one of them and it works good but it doesn’t update it in the database this is what we will do a little bit later on but now that we have all of this um I’m feeling that we need to finish styling uh to look to to make it look better so go back to your index and first of all inside the actually go to your layout and inside the stack what we need to do is we need to say okay we kind of don’t need this uh header here so to do that what we can do is um instead of having a stack selflo with a self-closing tag make it like this and inside here we will define stack dots screen we will give a name of this screen basically index that you have here so we’ll say index and we will pass some of the options to it so maybe some styling options which in our case it’s going to be header shown false we could you could also instead of doing header shown false you can have header uh title and say hello you could change not like this you could change here the title but for us what we need to do is just hide it well we can see another issue right away that all the text moved behind like in unsafe area let’s say that way well we can save it pretty quickly saying use safe area view and in this case we will use save area view from React Native uh so if we save it it right away moved out our content outside of this uh notch and inside the safe area so everything that it’s going to render here it’s going to render inside a safe area but let’s give it some styles so first of all if we do background color and do red we can see that it’s only taking up that much space but we need to take we need for it to take up the full space of the screen so we pass flex one basically saying take out the full space of the screen you are in we also need some margins on the side so now that you saw how it works I can remove the background color we also need some uh margins on the side so to do that we can say margin horizontal and it will add margins on here and on here uh if you could do also margin vertical to add it on top and on the bottom but for us we need it only uh horizontal okay now that we have this uh looking a lot better what we need to do as well is to add this uh if we go here reminders uh title and it is very easy i actually even have it prepared so I’m not going to waste your time too much i’m going to paste it and tell you what it does we’re simply uh displaying a text saying reminders we give it a font size of 27 we make it bold we give some letter spacing between each letter we give a color of this and we have a little bit of margin on the bottom of it so now our reminders look a lot uh better okay so what’s next what’s next is going to be um yeah okay I know so the next thing that we need to do even if we are displaying all of these reminders like uh like this the problem is that we still are taking the data one by one how can we make it dynamic so that in the future so if you actually go here and we can go to the next lesson which is type safe component so I was I was thinking to show the list right away but let’s follow the structure so yeah very quickly why do we need TypeScript and why do we use it well it helps us to detect errors errory so helps to tie catch also like type mismatches so for example if a component expects a string but gets a number it will complain about it so for example also if the if it will not have a um uh any type like here and here it will say well uh any type is not good enough to put it in simple words it also ha helps us to catch like these little errors for example if we would say reminder item remain it will complain and say maybe you meant reminder because that’s what reminder item is supposed to have in its type and also it makes it a lot easier to understand the code and understand what component expects and it what it doesn’t expect so I highly suggest everyone use at least start using you don’t need to actually apply the uh types everywhere so for example if you would leave it like this and release it to production nothing will crash everything will work but uh so you don’t need to apply all the types but at least start learning how to do that so inside the source let’s create a new folder called types and inside we can create let’s say reminder uh types.ts and in here let’s paste let’s copy all of this code so here we it’s actually pretty simple what we’re doing we are defining a reminder type and we know that this reminder should ex uh have a number with an uh with ID with an type of number and we can get all of this information from our database so if we go here or like our migration schema that we created or even the zod schema so it expects a ID of number of string it can have a note but note is either string or it can be null if it’s not provided it will have a completed boolean user ID or number and it will have a string of created uh at yes then we will have different types for inserting and for updating so for inserting uh when you’re creating new a reminder is a string which is required but a notes is an optional string that’s why we add this little question mark and even if it’s optional you can have it as a string or as a null value and user ID is also required as a type of number but for updating both of them are optional because you can update only one field so you can update the string um the reminder of a string or notes either a string or if you removed it it it’s going to be a null so now that we defined these types we can save them and um we can update our reminder list item component so here you can just copy but I will show you how to do that step by step because that’s that’s where we are seeing the complaints so at the top here let’s create a new type called I usually what I do just copy this name and add at the end uh props then we can start defining the types so what we know it is expecting to get a reminder it should expect to get a reminder item so let’s copy and paste that and this reminder item should be of type reminder here so it should have all of these fields so if we say reminder it would should suggest us to right away import it from types and we can hear that it imported from types but now it’s still complaining because we did not apply it here so how to apply it uh we simply add double dots here and we say this reminder all of these props okay it should have copied only one all of these props that we receive should match what we defined here so for example if you had here uh hey like we defined earlier you would have here inside also uh hey and it was of type string so because reminder props should receive basically two things but this hey can be also optional so it might be optional it depends on your case but yeah right now we’re only expecting the reminder item and this is how it should be structured so now you see that it’s no longer complaining it’s also a very good uh practice to here to provide names for your states so for example here we know that this is is completed and completed should be of type boolean if you pass a string if you pass a number it will complain so for example if I pass here two uh sorry if yeah if I pass here two it will start complaining because it says it’s not assignable to parameter of type boolean so it has to be either true or false and in our case the reminder item completed it is true or false okay so that’s that it’s very easy we’ll see how you use them even more in the previous tutorials we used them kind of in a especially in the Reddit clone in a more complicated way but this is a very good start to have basically just at least apply types to your components and the data they are receiving that way you will learn and if something you don’t understand like you can copy the error message paste it to any AI tool and it will help you to understand okay what’s the problem here okay so now that we fixed these types the one thing that we can finally get to is the lists because if as I told before adding all of the items like this and let’s say data we could even do like this way but that’s that’s insane that’s way too difficult uh and later on let’s say if people add more reminders in the application you need you would need to if you had this case come back here add new um new values after adding these new values submit your app to uh Apple review or Google play review and only then you can release with new values so this is not going to work we need to make them somehow uh dynamically render and uh basically it doesn’t matter how long the list is it should render them dynamically all the time and for that we can use a flat list from React Native flat list is a very cool list because it’s very optimized it’s rendering only the data that you see in some more screens but it is basically if you are thinking about rendering a list more times than not you are going to use a flat list there are different lists but yes this is what you should think of and it should expect a data and the data should be an array we know that this data that we get from the our query is an array so we can pass it like this but it’s not enough because we need to also define and tell to the flat list okay so how should I render this data so you could say okay so for every component that you render just render hello and because we have three three reminders it will render three hellos still not good enough we need to take the data from those reminders and uh dynamically display them so Every time um flat list goes through the list it goes let’s say inside first object then it goes inside second object then inside third option object and if there’s more continues to do that and every time it goes inside that object object it returns you here basically saying okay here is the object that I’m rendering now tell me how to render it and we will do it by simply saying item and let’s say let’s take reminder because we know that this item item has a reminder field so if we save it we can already see the reminder titles that it’s rendering here but it’s it’s even more powerful than that what you could do is you could say okay so for every item please uh render me reminder list item so the component that we just created of course we can right away see that uh the reminder list item TypeScript is helping us is expecting to get a reminder item so let’s just do that and even if you pass let’s say a reminder item incorrectly it will say that is not assignable to the type reminder that means the type is incorrect the data that you’re passing so you can see how much it’s helping us but if we say item it is because I’m writing this item i’m passing this item to the reminder list and if I go to the reminder list we know how to use all of this data so now if I save this we can see that everything is working very very well so we no longer now need these uh anymore and um we have a decent looking um reminder list of course uh let’s see if we uh align item center yes so we need that but um are they aligned correctly i’m not exactly sure but probably they are yeah you can play around with the styles a bit more but it this is how we want to Oh no yeah I see they are not uh especially this one is not correct because here we have so much white space so in here we can adjust it a little bit and say okay so the title reminder title we know that it always will be here so render it always but we will render the notes only if the reminder item has these notes so if you have them if they are defined if they are not null please render them only in that case so this is also bad because uh it will it might crash your application because you need to uh this should be a boolean basically true or false but notes is a string and uh we need to convert it to a boolean by doing double negation basically so first of all uh yeah doing double negation so if we save it we can see that now it looks good because now it there’s no white space under underneath it if it doesn’t exist and uh yeah it looks amazing so we can maybe increase a little bit the font size as well of the reminder so saying like font size 15 something like this and then maybe this one can be 13 yeah it depends on you you can play around with it but yes now that we have them uh one very important thing that we need to implement is actually uh finishing these and sending it to the data because now if we finish them we reload we can see that they’re not finished anymore so to do that we will use again tens query but we will use this time mutation from it so mutation is the difference between query and mutation mutation is kind of like a post patch uh request the thing that you want to make the changes in to your data and the query is the thing that you only ask for the data it returns and that’s it so what mutation will uh pass down is the mutate which is going to be the function basically that you call when you want to run the mutation so usually you do it on the button press or in this case we will do it on the button press so basically when the user clicks on this we can rename this mutate to our own so let’s say we can call it complete task uh and now you could either leave it like this and it would work if you called mutate but complete task makes a bit more sense it’s easier to read so now we will define like that it should be a use mutation from tenstack query and then this uh mutation should have also expects a few things so first of all it expects mutation function well that’s kind of uh easier to understand we need to somehow like say to it what it needs to do so for now we will uh leave it empty but later on we will add something inside there then it you this is no longer uh required but what we can do is we can call on success and basically when we call on success we are saying that um call this function if the mutation succeeds basically if it runs without any errors so we will do that also because we will need to do that and lastly we will say okay so what should happen if it didn’t succeed if there’s an if there was an error so here we will take the error from it and we will actually right away implement what it will do because we will simply display alert uh from React Native alert and we will say just display an error and also the error message you can adjust this like what happens on error however you want this is a very basic approach but it’s a good one okay so now let uh let’s define another function for mutation well that means we will be doing that inside the reminders service and um yeah uh let’s go and create a new function called so I will copy this one maybe close it and just rename it to complete reminder so here we’ll be completing the reminder but in order to complete reminder we will need uh two things well first of all our API expects ID to get ID and also it expects to get well is it completed or is it uncompleted so we will do that now we can build our query so uh our fetch function so we will say await and now we’ll say fetch inside here once again we could once again uh paste this whole link uh like long query and it would work but what we can do we can also create an environment file in the root here as well so if you create this environment file what we can do with it I will copy paste it and you can say like this is going to be our API URL and it’s actually 3001 and this API URL it’s very important to make it it expo public so that expo knows that it’s ex publicly available um environment variable and that I should be able to access it inside here so now uh I could very easily change my code to instead of calling this whole long let’s say um code what I can do is say okay so simply use process dot environment and then here there was a name I called it expo public and I think it was API URL and then we say slash slash reminders and then if I well now I won’t see that it’s working because I have this error in the renter item list but we can copy this and actually do the same here but of course we will call a different endpoint because we will be calling reminders but now you see okay so these are completely same how do we specify that it this is a post request no longer a get well for that we will open uh more options and here the first thing that we can pass is a method and this method if you remember is a post method because fetch by default is a get method we also need to pass some headers to say that okay the basically the content type will be a JSON type so this is what we need to pass for it and then we will pass in the body itself so basically all of the information but also we need to make sure that this body is in JSON format so that’s why we say JSON stringify and then we will pass um well either the full reminder or um actually only the like the parts that need to be updated so in this case it we only need to update the completed so we called it completed in our back end and then we call is completed like here and it um it will be the I think yeah let’s I think it’s going to be we need to like convert it to a different one so for example if it was completed that means we will uncomplete it uh or if it wasn’t completed we will complete it so if it’s true we’ll convert it to false if it’s false we will convert it to true uh later if we don’t need it I will remove it but yeah actually complete reminder is not a post request it’s a patch request because we’re updating and I forgot about it and we also need to pass the reminders and we also need to pass there the ID of the reminder so now this is getting uh better and the body is only passing the completed and now the rest of the part is exactly the same we were checking if the response is good failed to let’s say update uh a reminder and then if it’s good we will return a response so now we see that this is complaining because of the type so we can say that the ID should be of type number and it’s it’s very easy to add and the uh get completed should be of type boolean so now it’s good if we go back to our reminder list item we need to use this complete reminder function uh from the service reminder from this yeah reminder service so now if you hover on this we see that TypeScript is complaining because it expects an ID and is completed boolean and nothing is provided well first of all we need to the provide the ID and to do that it’s not that difficult because we have the ID here inside reminder item do ID and lastly we need to also um provide whether the reminder is completed or not and for that we will receive it in here so let’s say is reminder completed so you can pass the fun uh variables to mutations in here and then we will pass it back to here but now we see that uh this argument is of type void so we need to type this uh is reminder completed as well and now nothing is complaining everything is good so now what we can do is we can actually pass this once the user press on this touchable opacity we can do uh we can call complete uh not reminder because this is not going to be good we call complete task uh from here like mutation so once we call complete task what we need to do is we need to pass the current state of our task so we are passing this so if the current state is true we’ll pass it as true here but the reminder service is going to transform it and make it false so if we keep it like this um and now uh yeah now if we would change something it would not work so like if I uh and what is the error network request actually that’s very interesting to see so let’s see console.log response and let’s see what the response say to us let’s scroll to the bottom um doesn’t network request failed uh okay i think I wasn’t I didn’t refreshed it and it was showing me this error but now if I try to reload it we can see that after I clicked it it’s completed and if I click again and reload it it’s uncompleted but the problem is that we’re not showing the the like basically the changes in here right away we need to replo reload our app which is very bad so what we will do on success if it succeeded let’s take the data that it returns and set is completed to the data docompleted so basically what we’re doing here is we will set the data set this to completed only if we succeeded and the data is actually completed so now if I save it if I do this we can see that it already updates automatically uh if I yeah and if I reload it’s going to stay like that in theory you could h you could do this with um optimistic UI approach and uh call this even without on success but I just wanted to showcase you how to use this on success uh hook uh not hook like a function that it returns and um yeah this is exactly how you would do that so now we see that we can complete our uh reminders everything is perfect now we need to be able to create these reminders and um that is going to be done let’s see how uh I’m checking if the stream is still here people are still watching okay so now updating the reminder well we can see from our designs that the button to create I mean create new reminder should be uh in the index on the bottom and uh that button is actually I have it I think in my I don’t no I did not add it well never mind we can create it our own so we will have a pressable this is also basically how you wrap a button your custom buttons um and it’s imported from react native so in inside here we can add we need to add an icon that I have prepared as well because as if we see here it’s like a plus but icon i did not do it this way so now I also need to import it uh from React vector icons okay yes and type of React Native vector icons if I save it we see this plus sign right away where we need it and if we didn’t add here the flex it would be here at the top but now if we add this here it moves it where we need it to be and lastly we also need to add the text which is going to say new reminder the text should have be a little bit bigger so let’s pass some styles so the text will be something like font weight so you can also pass numbers here so 600 a little bit more but not too much and we also will pass a color of that little not little but cool orange color and let’s add a hashtag here let’s save it perfect now that’s still a bit um bad maybe we can make it also font size something like 16 and but it’s not uh really aligned how it should be how we would want it to be so we need to pass some styles to the box to the view or the wrap the parent component that wraps it so first of all we again if we want them to be in a row we will pass flex direction row we see that they are not really aligned in the middle so what we will do is we will align them centrally we need to also pass some gap between them so let me make it five and um yeah right now you don’t see it but here it does it will if I scrolled here on the bottom I am 100% sure that it will have no space here so what I want to do is I want to add some margin top and let’s make it 10 perfect so now we have this button um I also if I scroll I see that this reminders always stays on the top but this is shouldn’t happen and it’s very easy to fix inside the flat list we can pass list header component and we can simply pass that title as a list header component so now if I save and scroll it’s going to scroll together this is exactly what we wanted to achieve very good um so now how do we uh navigate to a new screen when we want to update well first of all we need to create a new screen inside our app and we will call it create and also update reminders because this is we can re reuse the same screen for both of the things very very easily and I will showcase you how to do that um so okay we have that um now let’s implement a very export default function uh create update reminder let’s make it return and let’s make it return a view and also a text so now if and import it from react native that’s very important so now if we say here create update save it and now how can we navigate here well if we go to the reminder uh index actually our home screen what we need to do to navigate there is as we already learned we can use link so we need to wrap everything with link from expo router so make sure you import it from expo router we no longer need this view here so we can remove it and now that we have okay now that we have this link here we it expects to have an href it’s like required the only thing that’s required and what we want to pass there is simply this name create update reminder create update reminder if we save it we can already see that something is messed up here and it’s because link only ex expects like to get a string or an icon inside it if you want to have your own some sort of um structure like some sort of a styling what you can do is pass it as child so what this does is basically saying okay I will pass this navigation to the children component but it’s very important that the children component has an on press uh like a parameter and we know that pressable has it so now it’s going to work and if we press here we are navigated to create update reminder screen of course we want to add some changes here and um to do that if we go to our layout we remember that we can style each of them separately so if we go to stack screen let’s close it here we need to pass the name that we’re trying to here implement changes so the name will be exactly this one create update reminder and now in here we can uh once again pass some options but because we will pass more options let’s make it like this so we will say options and inside here open the object and first of all what I really want to do is pass the presentation of model this is not going to be this model is not going to be native to Android because Android doesn’t have this kind of model so it will look a bit differently like a normal screen but it will still work so no worries about that i also because here if I click it’s the title is very random so I want to change the header title and the header title will be something like new reminder by default then I also want to add here like a back button or more like Apple reminders have it says cancel here so I can actually add my own uh header on the left there by simply specifying this and I will pass like a text i have it prepared here so you can just copy it and Okay um give me a what I’m forgetting the header left does not support attribute because it does not have props property uh let me actually type everything on my own because header left and I’m Yeah let’s see i will say text and what if I just say cancel here oh I did not import it from anywhere okay my bad so if I import from here now it will say cancel here but you already saw we can add some styles and I have a color prepared for that so let’s add them now the color is a lot better and we also want to once it’s clicked it should go back so right now it doesn’t do anything so to to go back programmatically we can pass this on press and we can reuse from expo router this little router and here by saying router uh back we can programmatically go back so if I click cancel now I’m going back to the main screen and it’s working like we want it to be perfect we have that ready so now we can start building our create update UI and it’s going to be pretty simple well first of all uh what I want to do oh again so there’s one more thing and maybe I will add it later yes so first of all what I want to do is add text inputs and um because we are severely over time um uh I see the questions uh Ryan I’m watching from Brazil very very nice i hope you will you will enjoy ready i’m when will be the other tutorial tutorial i missed this one we’re doing the tutorials at least trying to do every Friday maybe sometimes it can be every other Friday but we’re trying our best to do it every Friday but no worries because every tutorial you can find on uh this YouTube channel just go to it go to the live tab and you will see all of our tutorials there’s 300 of them uh so you’ll find what you need for sure but yeah so I will simply paste this little part um and I will explain real quick how it works well first of all let’s import the text input from React Native that’s very important and uh let me maybe remove this part it will be a bit easier to explain and now here you see some styles and I’m passing them in a different way and you might be thinking why and um well in the previous ones uh I was maybe even a bit uh lazy no I’m joking but um you can either pass the styles in line the same as we were doing here but if they’re getting longer like for example this one and this can be your homework actually or this one and especially in reminder item here we can definitely do that for this style but we can very nicely extract them in a stylesheet so we could create stylesheet from again it’s very important to import it from react native and we can say stylesheet dotcreate and we will create our own stylesheet so first of all we can add we can see here that we need a divider stylesheet so let’s call it like this and let’s add the styles for divider and I have them prepared here first of all we’re adding bordm bottom width you seen this and we’re saying the border bottom color should be light gray we also want to pass the styles to our input box so uh and we are usually doing that if they they have like a lot of different styles oh my mistake what’s no no uh so yeah we’re usually doing that if there’s a lot of styles like here or if the styles are repeating a lot then it’s a very good practice to extract them like this so here you can see that we set the background as white we gave some margin horizontal on the sides we also gave some margin on the top we also gave the border radius to this white box and of course padding very important because that’s how it would look without it and also we gave a gap between each of the input like this so yeah as your homework do this for um reminders list item and especially at least for this huge style here it’s a good practice to do it this way so now that we have these two inputs we need a way to track of what is being typed there and uh one way of doing that is using a state once again because whenever user is inputting something we need to first of all update it here so and also we need to store that data somewhere so we will do that with use state here so the use state will be a string only and the initial it will be initially it will be an empty string so we need to do the same for the notes as well so we’ll say set notes and it’s also going to be a string and uh initially empty okay that’s very good so now if we want to like how do we attach this text input to the state so that when someone is typing here I can have it inside my state every time and update it so that I could have the latest data when submitting well it’s very easy actually the only thing we need to do is pass to this text input two uh properties one is value so the value is going to be the actual like reminder and here the same value is going to be the notes in this case and also we need a way so when someone is typing to update this value so we will call on um on change text and when the text is being changed we will be calling either set reminders or on change text we will be calling set notes so in yeah in theory you could have it like this and have here text and then like this and pass text like this this would also work uh but um we can simplify it and have it like this and basically it will take that text basically all the parameters that it receives and it will pass it to a reminder so it we can simplify it just like that and the multi-line what it does is basically without it if we have if we typed something let’s say a very long it’s going to do it this way but if we have multi-line it’s going to go down so that’s what we want to do another thing that we want to add is we want to uh add a done button here at the top and uh how can we do that well in here in the layout we couldn’t really do it because after the done is pressed we will need to run the mutation and the mutation we will have it only inside here so how we can do it well first of all let’s wrap uh our our return statement in this like tag it’s uh kind of like a view tag but not really it just allows because return statement can have only one element inside uh so we need to wrap it like this because what we will do next is we will try to add stack dots screen we’re once again uh referencing this screen name so saying name and here now we can pass even more changes so for example if we couldn’t add something in the layout we can add it here very easily so for example here we need to add the header right uh and it should be a button and I already have uh yeah maybe I will do it like it will be a text button it will simply say done and the styles will have only a color so styles will have done like that of course we will have in here on press uh so once it’s pressed we will say we will call a function but for now we will console dot log and say uh pressed something like this okay so now it’s time for us finally to implement our mutation here to save the reminder and to do that it’s going to be quite similar to what we did in reminder list item so first of all uh at the top here we will uh define it so let’s say const we’ll have a mutate and we will rename it to save rem uh save reminder and we will also um continue by initializing it with use mutation from react query and this use mutation will once again have few things first of all mutation function and this will be we will call this service then it will have on success and we will need this and you’ll see why uh so on success we will at this time we will not need to receive the data so we can simply leave it like this but we’ll do some things here and then on error and on error I can simply actually even copy from reminder list because it’s going to be exactly the same uh just import the alert from React Native okay perfect so now we can go to the service uh and add this new service uh basically function which is going to be create uh creating a new reminder perfect so if we go here let’s maybe Okay let’s create from scr no let’s do this i’m already a little bit tired not going to lie and in here we will pass we will uh name it create reminder and what this create reminder expects is only new reminder object and this new reminder object if you remember in the types we already specified how insert reminder should look like so we can simply say insert reminder and don’t forget to import it from the types so now everything is good it’s typed let’s copy this because it’s going to be quite similar to updating the only things that we need to change is we’re no longer needing the ID because we’re calling the reminders but we’re calling the post not the patch and instead of providing like one uh object u one um value we will provide the full object of new reminder and now everything else once again is exactly the same so we’ll check if the response is good if it’s not we will throw an error and here we can also say fail to create a reminder instead so now once we go back here we can start using this create reminder from services very important and in here we need to pass this new reminder so this new reminder is going to be consisting of a few things well first of all it needs to have a reminder itself and a user which is mandatory and it might have notes might not have well so that means there will be some extra logic here so we can do it uh like this first of all we will say okay so we will start building our new reminder um object and this object will have as I said reminder itself so we’re taking it from here and passing as a reminder you could do it like this in theory saying that this is a key this is the value but we can simplify it and this will be key and value and then we will be needing the user ID because we don’t have any authenticated users here and we don’t have authentication yet maybe we’ll do it in the other tutorials but this is going to be the ID that we will pass which is ID one so okay user ID one that’s good and now we know that the notes is not mandatory so if we add here the notes it will always pass it and um basically kind of updated but it’s not it shouldn’t be always passed uh inside the request so what we can do is we can check like if notes is not empty what we will do is we will say that this new reminder object we should add another field called notes and then it’s going to be this notes right now we kind of see the issue and uh it says that notes does not exist on this type so what we need to do here we also need to specify the type here and it will be insert reminder uh and now everything is working because it insert reminder has if you remember um notes as a optional value and it’s either going to be a string and or a null so now after we do all this what we can do is we can return and call the create reminder function with this built reminder object so if we do that let’s try and uh let’s say here hello and for the notes uh we say test so if we click done and uh reload it actually after clicking done maybe um wait a second new reminder and let’s say hello test because now I know it’s um it should also close it but if we click it should we implement right okay so let’s do it like this on success uh let’s first of all already learn how to do that but programmatically close that reminder uh like model so in in expo query we will import the router and inside here we will say routerback so if the if the request succeeds we will call uh router back and go back so let’s see if this is actually a correct uh so we’re doing post with new reminder and if it’s not oh and we’re okay so let’s see let’s try to reload it let’s go to a new reminder and do something like this and uh oh okay so yes you can see that it’s already almost 12 uh in here so uh I am not calling this reminder anywhere so what we need to do in this done on header pressed left we need to call this reminder and yeah basically say this is where uh when it’s going to be executed so let’s go here to the top let’s see the name it’s called save reminder so let’s say save reminder let’s save it and now if we call it uh let’s see if it’s going to work yeah it worked it went back so I can add even another one maybe here you would even uh want to add like a loading state so that you cannot for example add here uh is uh it’s called it’s pending not is loading so let’s say this on press um yeah what we can do let let me think we want to make it disabled but on the button so maybe can we do it like this let’s see uh true and if we say like this and if I yeah it’s not pressable so that’s good so what we say uh what we will say is if it’s pending do not allow to click uh made a screenshot do not allow to click another time so let’s say if we create uh reload we already see those new values but yeah let’s try doing that yeah um is it is this pending i don’t actually remember uh let me console log console log is pending let’s save it it’s false so dis maybe on Okay now it worked but maybe I was pressing on a wrong button but now it’s working so now we can actually also try to test if it actually this works maybe it was no it actually works perfect so we can maybe even make this uh cons uh const is save button disabled so what we will do is we will say that this button should be disabled if uh is pending or uh reminder is not present then it will and it will return uh true then basically it should be disabled but we can simplify this a lot more and then we would need to say else return like false but we can do it very very nicely by simply extracting this and keeping it like this so we say is button saved uh is save button disabled either if it’s loading or reminder is not provided so we will do something like this and we will call it so now if we save it we go here we are no longer and we’re not able to press but here we are able to press and um yeah now we created but let’s see how many only one so that’s good but yeah now the problem is another one like if you add some data here it’s not not appearing here right away and how can we solve this this is a very bad thing so it’s actually quite easy to solve it what we need to do is we need to import the use query client from the tenstack query so here we have uh tack yeah here we will import use query client then inside here below let’s say our routes we will specify as const query client and we will say that we want to use this hook use query client and now we can on success what we can do is we can say query client and invalidate all the queries because now it’s not updating because the cache is basically the same it doesn’t know it needs to be updated but now we say that I’ll update every query that has a key of uh reminders and if you remember we are passing this key in our index so basically here it will update all of the uh queries that has this key so this is exactly what we want so now if I go here and say here updated and here updated almost correctly if I click save we can see right away right away it is appearing here which is exactly what we want to do amazing so now um I’m wondering is actually is pending uh is a news mutation but um I think so i think I think I think so but we can also check 10stack.com 10st query examples and um maybe something like okay so there’s is fetching maybe I can is pending okay not something I was looking for um is this how it is called okay I see a lot uh yeah I was reading the comments but yeah thank you guys very much viva thank you much uh Mayures um Eric Marin Golucas Mexico helpfully thank you thank you very much Jamie yes we are still live and we will be finishing it until the end even though it takes a bit longer thank you very much and yes Lee uh the video will be available in this channel so make sure to check it out after in the live tab and 6 hours in and still nobody understand that Lucas is just an AI robot yes uh Jane with this age of AI you can’t tell who is human and who isn’t yeah indeed indeed but we will be finishing it definitely i’m not sure about the is pending but where is the mutation yeah let’s quickly check out the M yeah here mutations so yes it’s pending perfect but uh mutation is currently running so yeah it is called that way perfect i’m not making it up so now and actually in order to test this completely because I really think I want to keep it high quality uh let’s try to console log it but yeah I can see it’s true if I click um something here it’s going to be true and then yeah perfect very good so now that we have all of these um what we need to do is we need a way to delete them and uh in order to delete them what we need to do is we need to open uh their detail page it’s going to be easy to do let’s just go to our reminders list item and where we have this ant design what we need to do is we need to simply pass on press function so we say on press and then we once again because we’re kind of um navigating there programmatically but um actually why should I do it this way i can do it with a link so yeah this is way better so let’s do it let’s wrap it with a a link and now let’s pass an href and this href will be basically where are we navigating well we know that we will be navigating to create update reminder uh create update reminder so for now let’s leave it like this so of course you see the styles are already kind of a little bit messed up so we will pass it to as child and because design like icons have on press it’s going to work and it’s opening this screen but now what we need to do is we need to populate the these fields with the existing data if we click on here so in order to know on which uh reminder and I already see this vertical line which I really hate so let’s quickly go to index and say here shows vertical indicator and we will say false do not show it so now it’s perfect looks amazing okay so when go let’s go back to reminders list item and how do we know to which uh reminder that we go well to know that we need to pass the ID here and we will pass this ID as a optional parameter because it’s not going to be always present it’s going to be only present if we click and if you go go to create update reminder from here if we click here it’s not going to be present okay okay so that is a little bit uh more interesting so to do that we will add a question mark say that we’re passing the ID and then uh in here we will pass and of course to enable these inputs we need to change it to this quote under the escape button never knew how it’s called probably will never learn but uh yeah so now in here we will pass the ID of the reminder so saying reminder item do ID and you see TypeScript is already suggesting which fields does it have that’s another huge bonus so we say ID so now if we click here we should be receiving the ID of the reminder that we clicked on so in order to get this ID and create update reminder we can extract it from the URL and it’s actually quite easy to do so at the top here we can say const we can uh we need to specify that we’re taking the ID sorry uh so yeah we’re specifying that we’re taking the ID so if we had here name you would have here name as well but we will keep it as an ID because that’s what we are passing right okay perfect this is where we have an ID and now how can we extract it well we can use use uh local search params from uh export router and in here we will take that ID um later on we will have um a little bit of an issue with the TypeScript so I will right away fix it and specify to that the ID that we will receive it’s not going to be an array it’s going to be a string ID of string so now let’s try to console log this ID and see if we’re actually receiving correct IDs so if we save it we can see already that it’s working maybe I do I have this no so if I go let’s say here it says four if I go here it says ID 8 but if I go uh new reminder it’s undefined but it’s still working perfect so now that we have an ID we can query the the reminder based on this ID but this query will be called only if the ID exists so how can we achieve that well first of all maybe um because we will need this ID to pass as a integer and we are receiving in a URL once again the same issue as a string let’s right away pse it like this reminder ID and let’s parse it to integer and let’s pass this ID here perfect so now uh now it’s going to be of type uh integer what’s exactly what we need so here we can call uh we can create our query which is going to be again defined the same as in the index we will be getting data oh no data we will be getting is loading lastly we will be getting error okay that’s good so sorry misclicks so now we’ll say okay so it’s going to be not you state sorry guys it’s almost almost we are almost at the end uh so we’ll be taking it from use query hook and let’s specify what we will do that so first of all we’ll be uh defining a query key and the query key at this point we will call it still reminders because we called it here here reminders and we kind of want to keep it the same because if let’s say here we are uh going to be um invalidating queries it will invalidate all the queries but in order to have all of these uh separately like stored and cached separately what we can do because this is an array we can pass a reminder id here also as a key so now this query will consist of basically reminders and key uh keys key pair of reminders and reminder ID but if I call invalidate queries and I call only with reminders it will still invalidate this query because it will check at the first one so that’s why we call it reminders here as well okay we also need to have uh specify a query function and the function here is going to be um boom and of course we will need to right now define that function but very important thing here is because we don’t want to run this query all the time if the ID is not present we shouldn’t be calling this query so we need to pass on one more property uh called enabled and what we will do is we will say only fetch if id exists so we are doing this um reminder id if reminder ex ID exists only do then uh do the fetching then if it doesn’t exist do not do fetch and we will not need that okay that’s good so now we can go to our reminder service and create once again uh another service to get a reminder by ID so let’s create export and maybe I will copy as well here and get reminder by ID okay so it will of course if we’re getting it by ID it will expect an ID and the ID will be of type number um okay so now we can very easily specify it’s going to look almost exactly like get reminders here uh the only difference is that we will need to pass here also the ID at the end so very easy to adjust it so yeah now that we have this everything else is going to be the same as always uh here we don’t need to really uh yeah we’re checking if the response is okay failed to get a reminder and we will return it so in here now we can call that function and uh I think we called it get reminder by id make sure it’s imported from services and now we need to pass the ID in here because um or actually I think we can right away instead of passing there we can pass it from here because we have it at the top so now once we do this let’s check console um log and let’s check if the data if we’re actually getting the data so let’s try to click at first it’s undefined then it loads the data and then we get it actually so that’s very good but what if we click on new reminder well it’s going to be undefined and this function is not even going to be called so for example we could say here console.log uh called and uh if we go here it’s going to be well called but if we go on here it’s not even going to be called so that’s amazing exactly what we want okay so now that we have this reminder we need to populate the data uh with in these fields with already existing data here and to do that well we can uh introduce a new hook called use effect and this hook will help us to do that uh very nicely but actually before that even before that I would want to handle the loading case because if you saw there was at first some loading the data was undefined and then it was defined so let’s say if it’s uh is loading we will add basically exactly the same styles as here and the error is also going to be the same so you can just copy and paste it here but we need to show uh import the this one first of all yeah and we need to say like handle these state it’s very important um so now you can if you go here you will see a small loading screen which is exactly what we want but now what we will do is we will also call use effect uh query hook not query and once this hook uh when is this hook called well first of all it depends really on the dependencies that you that you have here so for example if I only have a empty array so it’s going to be uh called only when the component mounts so for example here it’s called and I can write anything whatever it’s not being called but if I pass any kind of dependencies here so for example let’s put reminder state as a dependency and now let’s try to call it again when uh I did not save it so yeah let me open it rendered more hooks than in the previous render so Oh okay i need to have this it’s very important never have uh these before uh hooks basically hooks should should always go before because the component every time need to render the same amount of hooks and why it was failing and it’s actually very good that it failed because I have an um I can explain to you because once you once we add it here what it does at first when this component mounts because it’s loading it will return this and it will never go uh down once the loading finishes it will go here and it will render this hook but now because we in the previous render we did not render this hook it will fail and throw us an error saying that we now we’re rendering more hooks than in the previous render so it’s very important to not have these returns uh before any of the hooks that you have here yeah so now if we save it it’s going to work and uh let’s go here so it is called now and now if I type every time this reminder state changes we are calling it again and again and again so this is what how we will reuse um our let’s say use query and how we will set the data that we receive from the API to this already existing states so what we can do here is we can go uh and say okay call this hook on first render and then every time when you uh when the data changes here basically when this changes call it again uh like yeah render it again call it again so what we will do first of all we will check if we have the data so if the data is not empty or undefined then we can call set reminder and set data dot reminder and also we can set set notes and say data do notes perfect uh now if we save it and go here we all right away see the data being populated so now if I press on let’s say the one with notes also we see this right away so this is how we will be able to update it but of course we need to create a one more mutation to be able to update this um um yeah to be able to update it so just under the save let’s create one more last mutation co well actually there will be delete but it’s a very easy one so almost the last mutation called mutate and let’s call it update uh rem reminder perfect so now uh we can also follow the old use mutation structure yeah how is it called let’s add some of these to make it a bit more of the same uh yeah make all of them the same so now inside here once again let’s follow uh how we did before we will call this uh we will have here mutation function which we will need to call and we will have some more changes here and also we will have oh sorry we will have here on su not unsettled on success which we will again we will be calling to invalidate the data and show right away the new changes that we just did and lastly the error is going to stay the same so I’m just going to copy it and paste it so right now actually also success is completely the same because the only thing we need to do when it succeeds is to invalidate the rem all the reminders and then go back so that we could see the changes right away so in this mutation we will have uh a little bit differently so we will also want to build this new reminder basically that we are updating to and in here we will pass the reminder because you can only update reminder notes and completed and also we will have the notes but we will pass the notes only if it exists uh basically if it’s not empty if it’s not uh empty string yes so if it’s an empty string we will pass it null because that’s the structure we kept it uh we kept in our database and that’s what we want to maintain basically if if the user removes um the string and leaves it let’s say goes here removes this and wants to update we need to set it as null and not as an empty string uh so yes that’s that’s what we’re trying to achieve here and also lastly we will just return and we will return the function that we will create in the reminder services now so let’s go here and let’s do like this let’s call it uh okay so update old reminder and in here uh this update function should expect uh the ID that we’re trying to the reminder that we’re trying to update and also the fields so ID I don’t know why I removed it and also it will be updated uh reminder so fields basically so in in here the type will be update reminder type the ones that we here specified okay so now we can call uh this very similarly to actually completing a reminder and we could have actually reused it but let’s make it that way so now that we have all of this code uh the only real difference that we are making here is that we are not passing only the completed but we’re passing the whole no this one the whole updated reminder object so that we could have easily and if you want a challenge you can try to uh implement it basically I just wanted to have a little bit separate concerns and yeah make it maybe a bit cleaner more structured so in here now once we return we can call update all reminder from this service make sure it’s important yes and in here we need to only pass the reminder ID so it’s going to be I think yeah reminder id and also we will be passing the new reminder object that we’ve built here perfect that’s not it we need to understand and basically which function to call or is it going to be called basically uh done or save new yeah save new reminder or update all reminder so to do that what we will do is we will create one function called ondone pressed and what this function will do is it will decide what are we calling so what how we will decide simply if reminder id exists that means we are in a detailed page and we will simply call where is it um we will call this update reminder function yes otherwise if it doesn’t exist uh that means we’re 100% uh saving and creating a new reminder so we will call save reminder function mutation which is here now we need to pass this function to our done instead of calling always save reminder we will call it uh undone pressed so we’ll go here and we’ll check which we need to function to call and it will call appropriately so now if we go let’s say and create a new one let’s say creating um new reminder and let’s say in notes we can add creating new notes if we save it we see that new reminder appeared but if we go here and let’s say rename to update new reminder and update new notes if we save it we can see that it updated this uh reminder itself so that means everything is working as we need it’s very cool very good uh so yeah now we are left with the last last thing and it’s going to be very easy to implement we need a way to remove these reminders because now we are cluttered in here so to do that we will add once we go here to update reminder we will add one more button on the bottom and here again we will decide uh whether to display it or not with saying like if reminder ID exists only then display it and I already have the styles I’m not going to waste too much of of your time here so let’s import pressible uh let’s have this and the the styles will be uh for like as the input box the same as these two the only thing is that for now we don’t have this so let’s say console log and let’s pass for now ss or maybe press okay so now something doesn’t look exactly correct and I don’t really uh why is it exactly like that because of input box but um I wanted to have them Oh okay okay i see because we have them in the same view but it should actually be outside of this view and be as its own separate box to click on delete yes perfect so now let’s simply uh define our last last mutation which is going to be for deletion so okay maybe let’s do it okay let’s do it here so we will create once again we learned it how to do it already so we will call here maybe delete or remove i’m not sure maybe remove reminder and then in here once again equals use mutation hook in here we specify the mutation function which is going to be something that we will create in the services so for now let’s do it this way we will have on success and on success is once again we are we need to invalidate the data because um we need to reflect all of these changes everywhere so we can copy exactly like this and actually error is also exactly the same so we the only thing we need to do is create this uh remove service so if we go to reminder services in here um for the delete we only need actually the um the ID so let’s copy this one uh create it like this let’s rename it say um how delete reminder maybe reminder and now uh that we specify this function let’s implement uh the the um the actual fetch request so let’s say const response equals we again we’re waiting for it where fetch calling fetch and here we’re specifying the link so maybe I will yeah it’s going to look very similar to this so URL so that’s what I’m going to do but if we remember this is actually a delete um request so we need to specify the method of delete so once we do that we can follow exactly the same as here uh structure and uh now we can go to our create update and call delete reminder by passing the reminder ID at here at the top that we have so now let’s test the deletion so now we can see that even if we reload that update new reminder is at the top but if I go here and click okay I forgot to pass it uh as a function so how did I call that mutation remove reminder yes here so if we go here we call remove reminder and let’s save it so now if I click here once we are back we are no longer seeing that anymore so as sad as well if we delete it’s no longer here so it’s working it’s uh yeah perfect uh we are finished with uh finally finished with our full stack application it took us a little bit longer than expected maybe I went too deep uh uh in some of the concepts but I hope it was valuable so yeah hopefully I really did not forget anything but um even if I did we already did quite a lot and also for yourself you can try to implement it even more things so for example one very good um task would be or even let’s say um exercise to do exactly the same but with users because we already created kind of uh the database uh we have the users there so try to do exactly the same and also maybe a list you can also have here but without completing just try to get those users and maybe implement a way to delete those users or if you have more knowledge in the on the like react native front end try to create different lists like um Apple reminders have so for example you could have a completed list and incomplete list this is actually one of the things I wanted to do as well but um yeah we’re severely over time so um yeah you can try doing that yourself so for example if you click go to all uh you will see incomplete or if you click go to completed tasks you will only see these and this is very good for you to continue learning on top of this and um deepening your knowledge and also if you have any questions just uh leave them in the description below oh not in the description in the comment section below i’m always trying to get back and u trying to answer these questions as much as I can find at least a little bit of time maybe sometimes during the weekends uh yeah I really want you to transfer all of my knowledge to you and uh if I can help I will definitely always try it out you can also use cajbt if I am not replying instantly maybe you’ll find your answer there but um yeah I will always be there to try at least and help you but yes hopefully you enjoyed uh this long long um tutorial uh hopefully at least one of you will finish it and yeah that would make me very happy i see some very nice words also and um I’m very thankful for these words uh and um yeah hopefully we’ll meet very soon again and we’ll have uh more of a chitchat zuhari awesome video it was very informative thank you thank you very much for staying for that long i really really appreciate it uh how what great job thank you very much Leonel super understandable thank you very much for this video these comments is actually what’s uh driving us forward and why I’ve stayed for so long and uh yeah even though at the end my wording got a little bit uh let’s say wonky but I tried I tried my best to keep focused keep it informative and yeah Eugene first time being here i hopefully I’ll see you more i usually remember all of the uh people that are at least commenting and we have some of the people here that are coming back at least to say hi for every every tutorial which is insane like wow it’s wow uh yeah guys thank you very much i really appreciate you being here with me and I’ll see

By Amjad Izhar
Contact: amjad.izhar@gmail.com
https://amjadizhar.blog
Affiliate Disclosure: This blog may contain affiliate links, which means I may earn a small commission if you click on the link and make a purchase. This comes at no additional cost to you. I only recommend products or services that I believe will add value to my readers. Your support helps keep this blog running and allows me to continue providing you with quality content. Thank you for your support!

Leave a comment