Building a Full Stack Workout Tracker with React Native & MongoDB

notJust․dev128 minutes read

The project involves using React Native, Expo, SDK 50, GraphQL API with IBM Stabs, API Ninjas for data, MongoDB for storage, and Coral for sending POST requests, with today's goal being to save new sets to the database and implement features like charts, filtering, and pagination. To ensure functionality, correct API keys must be included, the GraphQL API must connect to API Ninjas and MongoDB, and the React Native application must be tested for adding new sets and viewing exercise details.

Insights

  • IBM Stabs facilitates quick GraphQL API creation with a simple command, aiding in project development.
  • The Coral utility is used to send a POST request to the MongoDB data endpoint with the action "insert one" to insert a set.
  • To ensure real-time updates, the query key of the affected query is invalidated using the query client after a mutation, allowing for automatic UI updates.
  • Implementing a context provider named "authContext.jsx" facilitates global state management for sharing data between components, such as storing and accessing usernames.

Get key ideas from YouTube videos. It’s free

Recent questions

  • How is GraphQL utilized in the project?

    GraphQL API created with IBM Stabs for data retrieval.

  • What is the purpose of MongoDB in the project?

    MongoDB used for storing set information.

  • How are new sets saved in the database?

    Sets inserted using GraphQL mutation with variables.

  • How is user authentication handled in the project?

    Device ID used for linking sets to users.

  • What features are planned for future development?

    Goals include charts, searching, filtering, and pagination.

Related videos

Summary

00:00

"Building React Native App with GraphQL API"

  • The project utilizes React Native for the front end, Expo, and SDK 50 version for navigation management.
  • The back end involves building a GraphQL API using IBM Stabs, connecting and retrieving data from various sources.
  • The exercise data source relies on an external REST API named API Ninjas, while MongoDB is used for storing set information.
  • IBM Stabs facilitates quick GraphQL API creation with a simple command, aiding in project development.
  • This session is part two of a project series; part one focused on UI creation, GraphQL API setup, and MongoDB data retrieval.
  • Today's plan includes saving new sets in the database, linking sets to specific users, implementing charts, searching, filtering, and pagination.
  • To follow along, download the updated asset bundle from assets.noas.dodev/workouts or access the source code on GitHub.
  • Ensure API keys are updated for API Ninjas and MongoDB connections to function correctly.
  • Verify the deployment of the GraphQL API connecting to API Ninjas and MongoDB to confirm data retrieval.
  • Run the React Native application connected to the GraphQL API to test functionality, including adding new sets and viewing exercise details.

18:47

"Inserting Sets into MongoDB with GraphQL"

  • The integration for creating and saving sets in a MongoDB database was started in a previous live stream using the Coral 0.1 folder.
  • The Coral utility is used to send a POST request to the MongoDB data endpoint with the action "insert one" to insert a set.
  • A simple Coral request example was shown to demonstrate how adding a set through the REST API works.
  • By sending a POST request with exercise, weight, and reps parameters, sets can be inserted into the database.
  • GraphQL with Staben is used to create a GraphQL endpoint that sends a POST request to insert sets into the database.
  • The document to be inserted should include exercise (string), weight (float), and reps (integer) parameters.
  • The input document in GraphQL should be specified as an object with the required parameters.
  • The mutation in GraphQL is renamed to "insert set" and the variables are specified as a new set object.
  • The values for exercise, weight, and reps should be added as variables in the mutation to avoid hardcoding.
  • The collection, data source, and database values are hardcoded in the post body to simplify sending requests.

46:21

Executing GraphQL Mutations in React Native

  • The variables for the new set will be set, and upon execution, it should work.
  • The inserted ID from steps one to three needs to be copied and checked in MongoDB by filtering for the object ID.
  • The mutation document needs to be copied for execution in the React Native application upon pressing the add button.
  • The GraphQL request needs to be imported, and the mutation document pasted for execution.
  • The useMutation hook needs to be defined in the new set input component to send an object with the new set for execution.
  • The mutation function will use the GraphQL client to request the mutation document with the variables.
  • The mutate function needs to be called with the new set variables upon pressing the add button.
  • Reps and weight need to be taken from user input and transformed from strings to numbers for accurate data entry.
  • The exercise name needs to be sent to the new set input component from the Details page for accurate data entry.
  • Error handling needs to be implemented for failed set additions, and conditional rendering for error messages.

01:11:25

Optimizing Scrollable Sets List in Application

  • The sets list is a flat list used in the application's detail screen, rendered inside a scroll view.
  • Having two scrollable elements with the same direction nested within each other is not recommended as it causes confusion in scrolling.
  • To ensure the entire page is scrollable, a property called list header component should be sent to the flat list, allowing the header to scroll with the items.
  • The header component is managed from the parent component, enabling changes from outside the sets list.
  • To optimize code cleanliness, the header can be extracted into a separate component, enhancing code organization.
  • The scroll bar can be hidden by setting the vertical scroll indicator to false in the flat list within the sets list.
  • Filtering and displaying only sets related to a specific exercise involves implementing a filter in the MongoDB query.
  • The filter object specifies the exercise to match when retrieving items from the database.
  • The filter parameter is added to the MongoDB query in the API, allowing for exercise-specific data retrieval.
  • To automatically update the UI after a mutation, the query key of the affected query is invalidated using the query client, ensuring real-time updates without manual intervention.

01:36:41

Improving Query Validation and User Authentication in App

  • The issue is with query invalidation, where adding a set should only update the relevant query for that exercise.
  • By matching variables in the query, only the specific exercise query is validated, ensuring accuracy.
  • Resetting fields upon successful execution rather than immediately ensures better functionality.
  • Linking sets to users requires an authentication system, but for simplicity, linking to a device ID is chosen.
  • The Expo device package can provide device information, including a unique device ID.
  • Implementing a simple authentication form to collect usernames is preferred over device identifiers due to app store policies.
  • Creating an "off" screen for user authentication involves setting up a username state variable and a text input field.
  • Styling the authentication screen with labels, input fields, and a sign-in button for user interaction.
  • The sign-in button triggers a function to store the entered username for future use in the application.
  • Storing the username globally allows for easy access when querying user-specific data, like sets and exercises.

02:04:57

Creating Global State with Context Provider in React

  • Global state stores the username for later use, inaccessible in screens, necessitating a context provider.
  • To create a context provider, a new file named "authContext.jsx" is made in a folder for providers or contexts.
  • The context provider facilitates implementing global state and sharing data between components.
  • The context is created using the "createContext" function from React, initially an empty object.
  • The context includes "authContext.Provider" to expose variables and a consumer to retrieve values.
  • A component named "AuthContextProvider" is defined to wrap around the context provider.
  • The "children" property in React allows passing down components to access the username.
  • The context provider is rendered in the root layout to grant all screens access to the username.
  • A custom hook "useAuth" simplifies access to the context, enabling username retrieval for redirection.
  • Updating the username in the global state involves calling "setUsername" with the local username inputted.

02:27:15

"User-specific exercise data with pagination and charts"

  • Adding the username to the query key prevents multiple users from overriding the same query.
  • Refreshing the page reveals exercises, with the ability to add more.
  • Different users can sign in and view their own exercise data.
  • Sets or data in the database are successfully linked to specific users.
  • Goals include implementing charts for progress, searching, filtering, and pagination.
  • Pagination is crucial to load more exercises beyond the initial set.
  • The REST API handles pagination with an offset parameter.
  • Implementing pagination in GraphQL involves adding an offset parameter.
  • In React Native, implementing pagination involves using the useInfiniteQuery hook.
  • Implementing infinite scroll lists allows for automatic loading of more items as the user scrolls.

02:53:49

"Efficient Pagination and Dynamic Search Implementation"

  • Implement a function to load more content, ensuring it doesn't fetch the same page twice while scrolling.
  • Successfully accomplished pagination by committing changes related to pagination.
  • Next goal is to implement searching functionality, starting with the user interface for a search bar.
  • Utilize the search bar from the platform's stack navigator, following the React Navigation documentation.
  • Set up the search bar options in the stack screen for the home screen with exercise lists.
  • Create a state variable to store search information and implement a callback function for search bar actions.
  • Debounce the search term to prevent excessive server requests and enhance user experience.
  • Successfully implement searching functionality with the ability to dynamically search and display results.
  • Addressed a bug related to header size and item visibility, adjusting padding to resolve the issue.
  • Plan to work on implementing charts for progress tracking, considering data requirements and library usage.

03:25:48

Creating Interactive Progress Graphs with React Native

  • Progress graph rendering involves starting with a dummy chart and using user data to display a proper chart.
  • Rendering a line graph requires importing the line graph from React Native Graph and providing points and animation properties.
  • Points for the line graph should include a date and a value, initialized as an empty array and false for animation.
  • Dates for the points can be initialized using JavaScript's date constructor with specific values.
  • Extracting dates from MongoDB object IDs can be achieved using specific JavaScript functions.
  • Displaying human-readable dates can be done using date-fns library for formatting.
  • Mapping sets on the graph involves transforming sets data into points with dates and values.
  • The progress graph requires an array of sets to plot on the screen, which can be passed as a property.
  • Calculating values for the points can involve multiplying reps by weight to determine volume.
  • Additional features like adding pinch gestures for navigation and specifying value ranges can enhance the graph functionality.

03:57:36

Enhance UI with muscle variable for filtering.

  • When updating the UI, ensure to add the muscle variable in the query function alongside the name to enable filtering based on different parameters such as muscle, difficulty, and more as per the API documentation. Stay tuned for the next tutorial on implementing monetization with RevenueCat this Friday, and continue enhancing the workout tracker project to advance as a React Native developer.
Channel avatarChannel avatarChannel avatarChannel avatarChannel avatar

Try it yourself — It’s free.