How to send this data to Database using Express and MongoDB and React Native ? Issue with Sending Data to Backend Endpoint in React Native

I’m encountering an issue with sending data from my React Native frontend to a backend endpoint. I’ve provided the relevant code snippets below.I’m encountering an issue with sending data from my React Native frontend to a backend endpoint (/onboarding/v3). Below, I’ve provided relevant code snippets and additional details about my setup.

enter image description here

User Model:

I’m using a MongoDB database with Mongoose to define my user schema. The schema includes fields for name, email, password, and various other user details. Of particular relevance to this issue is the areasOfInterest field, which is an array of objects containing title and items properties.

I have a React Native component AreasOfInterest where users select their areas of interest and rate their expertise. Upon pressing a “Next” button, I want to send this data to the backend.

I would appreciate any guidance on how to properly format the data and resolve the issue with sending it to the backend endpoint. I’ve included relevant code snippets below for reference.

Backend Endpoint:

I have a backend endpoint /onboarding/v3

Please fix my code
My User Model is below. after it

const mongoose = require("mongoose");

// Define schema for items within an area of interest
const InterestItemSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  stars: {
    type: Number,
    min: 1,
    max: 5,
    default: 1, // Default to 1 star
  },
});

// Define schema for areas of interest
const InterestSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  items: {
    type: [InterestItemSchema],
    default: [],
  },
});

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  image: {
    type: String,
    required: true,
  },
  friendRequests: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  ],
  friends: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  ],
  sentFriendRequests: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  ],
  First_Name: {
    type: String,
    default: "",
  },
  Last_Name: {
    type: String,
    default: "",
  },
  Pronoun: {
    type: String,
    default: "",
  },
  Gender: {
    type: String,
    default: "",
  },
  Race: {
    type: String,
    default: "",
  },
  Country: {
    type: String,
    default: "",
  },
  State: {
    type: String,
    default: "",
  },
  City: {
    type: String,
    default: "",
  },
  Role: {
    type: String,
    default: "",
  },
  Student: {
    type: Boolean,
    default: false,
  },
  Mentor: {
    type: Boolean,
    default: false,
  },
  Affiliation: {
    type: String,
    default: "",
  },
  Headline: {
    type: String,
    default: "",
  },
  Education: {
    type: String,
    default: "",
  },
  Major: {
    type: String,
    default: "",
  },
  Degree: {
    type: String,
    default: "",
  },
  GradeYear: {
    type: String,
    default: "",
  },
  areasOfInterest: {
    type: [InterestSchema],
    default: [],
  },
  Career_Goals: {
    type: [String],
    default: [],
  },
  withOrgOnly: {
    type: Boolean,
    default: false,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
  updatedAt: {
    type: Date,
    default: Date.now,
  },
});

const User = mongoose.model("User", userSchema);

module.exports = User;

// Backend Endpoint (Working (not sure about onboarding/v3) )

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
const os = require("os");
const app = express();
const morgan = require("morgan");
const port = 8080;
const cors = require("cors");
const router = express.Router();

app.use(morgan("dev"));
app.use(cors());

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
const jwt = require("jsonwebtoken");

const User = require("./models/user");

// POST endpoint for onboarding/v3
app.post("/onboarding/v3", async (req, res) => {
  try {
    const { userId, areasOfInterest } = req.body;

    const user = await User.findById(userId);
    console.log(user.name);
    console.log(areasOfInterest);
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }

    user.areasOfInterest = areasOfInterest;

    await user.save();

    res.status(200).json({ message: "Areas of interest updated successfully" });
  } catch (err) {
    console.log("Error updating areas of interest", err);
    res.status(500).json({ message: "Error updating areas of interest" });
  }
});

// Frontend Main Page.

import React, { useState, useContext } from "react";
import {
  View,
  Text,
  SafeAreaView,
  TextInput,
  TouchableOpacity,
  FlatList,
} from "react-native";
import Icon from "react-native-vector-icons/FontAwesome5";
import { CheckBox } from "react-native-elements";
import { AntDesign } from "@expo/vector-icons";
import axios from "axios";
import { UserType } from "../../UserContext";

const NavigationLine = ({ active }) => (
  <View
    style={{
      flex: 1,
      height: 5,
      backgroundColor: active ? "#57D5DB" : "#DBD4D4",
      marginHorizontal: 5,
    }}
  />
);

const InterestList = ({ data }) => {
  const [expanded, setExpanded] = useState(false);
  const [ratings, setRatings] = useState(Array(data.items.length).fill(0));
  const [selectedItems, setSelectedItems] = useState(
    Array(data.items.length).fill(false)
  );

  const handleRatingChange = (index, rating) => {
    const newRatings = [...ratings];
    newRatings[index] = rating;
    setRatings(newRatings);
  };

  const toggleCheckbox = (index) => {
    const newSelectedItems = [...selectedItems];
    newSelectedItems[index] = !selectedItems[index];
    setSelectedItems(newSelectedItems);
    // Reset rating to 0 when unchecking the checkbox
    if (!newSelectedItems[index]) {
      handleRatingChange(index, 0);
    }
  };
  return (
    <View>
      <TouchableOpacity
        onPress={() => setExpanded(!expanded)}
        style={{
          flexDirection: "row",
          alignItems: "center",
          backgroundColor: "#F1F1F3",
          width: "90%",
          height: 50,
          borderRadius: 20,
          marginTop: 15,
          paddingHorizontal: 20,
          borderColor: "#D9D9D9",
          borderWidth: 1,
          marginHorizontal: 15,
        }}
      >
        <Icon
          name={expanded ? "caret-down" : "caret-right"}
          size={15}
          color="#9C9C9C"
        />
        <Text style={{ flex: 1, marginLeft: 10 }}>{data.title}</Text>
      </TouchableOpacity>
      {expanded && (
        <FlatList
          data={data.items}
          keyExtractor={(item, index) => index.toString()}
          renderItem={({ item, index }) => (
            <View
              style={{
                flexDirection: "row",
                alignItems: "center",
                backgroundColor: "#F1F1F3",
                width: "90%",
                height: 50,
                borderRadius: 20,
                marginTop: 5,
                marginHorizontal: 15,
                borderWidth: 0.1,
              }}
            >
              <TouchableOpacity
                onPress={() => toggleCheckbox(index)}
                style={{ marginLeft: 20, marginRight: 10 }}
              >
                <Icon
                  name={selectedItems[index] ? "check-square" : "square"}
                  size={20}
                  color="#000"
                />
              </TouchableOpacity>
              <View style={{ flex: 1 }}>
                <Text style={{ fontSize: 13 }}>{item}</Text>
              </View>
              {selectedItems[index] && ( // Show stars only if checkbox is selected
                <View style={{ flexDirection: "row", marginRight: 20 }}>
                  {[1, 2, 3, 4, 5].map((star) => (
                    <TouchableOpacity
                      key={star}
                      onPress={() => handleRatingChange(index, star)}
                      style={{ marginRight: 4 }}
                    >
                      <AntDesign
                        name="star"
                        size={20}
                        color={ratings[index] >= star ? "#FFD700" : "#D3D3D3"}
                      />
                    </TouchableOpacity>
                  ))}
                </View>
              )}
            </View>
          )}
        />
      )}
    </View>
  );
};

const AreasOfInterest = ({ navigation }) => {
  // Use userId to send backend
  const { userId, setUserId } = useContext(UserType);
  const interestData = [
    {
      title: "Accounting",
      items: [
        "Financial Accounting",
        "Cost Accounting",
        "Managerial Accounting",
        "Auditing",
        "Tax Accounting",
        "Forensic Accounting",
      ],
    },
    {
      title: "Finance",
      items: [
        "Investment Management",
        "Financial Risk Management",
        "Corporate Finance",
        "Public Finance",
        "Personal Finance",
      ],
    },
    {
      title: "Human Resources",
      items: [
        "Learning & Development",
        "Performance Management",
        "HR Information Systems",
        "Compensation & Benefits",
        "Recruiting & Staffing",
        "Organizational Structure",
        "Employee & Labor Relations",
        "Diversity Equity & Inclusion",
      ],
    },
    {
      title: "Information Technology",
      items: [
        "Systems Security",
        "Data Management",
        "IT Management",
        "Network Administration",
        "Software Development",
        "Web Development",
      ],
    },
    {
      title: "Legal",
      items: [
        "Litigation",
        "Risk Management",
        "Contract Law",
        "Import/Export Law",
        "Compliance Policies & Procedures",
        "Property Law",
        "Intellectual Property Law",
        "Employment Law",
        "Ethics",
        "Law Enforcement",
        "Criminal Justice",
      ],
    },
    {
      title: "Manufacturing",
      items: [
        "Plant Management",
        "Fabrication & Machining",
        "Reliability & Asset Management",
        "Procurement",
        "Distribution",
        "Production Installation",
      ],
    },
    {
      title: "Operations",
      items: [
        "Improve Processes",
        "LEAN & Six Sigma",
        "Production Planning & Control",
        "Quality Management",
        "Supply Chain Management",
        "Design Process",
      ],
    },
    {
      title: "Marketing & Communication",
      items: [
        "Sales Support",
        "Marketing Communications",
        "Advertising Strategy",
        "Pricing Strategy",
        "Market Research",
        "Social Media Strategy",
        "Brand Management",
        "Copy & Content Creation",
        "Imaging/Graphics",
      ],
    },
    {
      title: "Sales",
      items: [
        "Capture Management",
        "Building a Book of Business",
        "Channel Strategy",
        "Sales Forecasting",
        "Enterprise Sales",
        "Inside Sales",
        "Objection Handling",
        "Business Development",
      ],
    },
    {
      title: "Management",
      items: [
        "Delegation",
        "Emotional Intelligence",
        "Improve Processes",
        "Product Management",
        "Project Management",
        "Decision Making",
        "Negotiation Skills",
        "Develop Others",
        "Change Management",
        "Priority Management",
        "Effective Communication",
        "Conflict Management",
      ],
    },
    {
      title: "Leadership",
      items: [
        "Team Building",
        "Shaping Culture",
        "Setting Vision & Strategy",
        "Strategic Thinking",
        "Product Development",
        "Service Development",
        "Value Creation",
      ],
    },
    {
      title: "Healthcare",
      items: [
        "Dentistry",
        "Health Sciences",
        "Physician",
        "Veterinarian",
        "Pharmacist",
        "Healthcare Management",
        "Patient Care",
      ],
    },
    {
      title: "Education",
      items: [
        "Teaching",
        "Education Administration",
        "School Counseling",
        "Curriculum Development",
      ],
    },
    {
      title: "Consulting",
      items: [
        "Management Consulting",
        "Corporate Consulting",
        "Independent Consulting",
      ],
    },
    {
      title: "Government & Public Administration",
      items: [
        "Revenue & Taxation",
        "Law Enforcement",
        "Public Management & Administration",
        "Environmental & Resource Planning",
        "National Security",
        "Governance",
      ],
    },
    {
      title: "Customer Service",
      items: [
        "Customer Retention",
        "Customer Management",
        "Customer Support",
        "SaaS Customer Experience",
      ],
    },
    {
      title: "Engineering",
      items: [
        "Civil Engineering",
        "Chemical Engineering",
        "Mechanical Engineering",
        "Electrical Engineering",
        "Industrial Engineering",
        "Aerospace Engineering",
        "Biomedical Engineering",
        "Environmental Engineering",
        "Computer Engineering",
        "Materials/Textiles Engineering",
        "Nuclear Engineering",
        "Architecture",
      ],
    },
    {
      title: "Sciences",
      items: [
        "Agricultural Science",
        "Social Science",
        "Biology",
        "Chemistry",
        "Political Science",
        "Physics",
        "Psychology",
        "Mining & Petroleum",
      ],
    },
    {
      title: "Social Services",
      items: [
        "Therapists",
        "Probation Officer",
        "Rehabilitation Counselor",
        "Career Counselor",
        "Social Worker",
        "Substance Abuse Counselor",
        "Mental Health Counselor",
        "Clergy",
      ],
    },
    {
      title: "Creative / Design",
      items: [
        "Creative Arts",
        "Graphic Design",
        "Interior Design",
        "Product Design",
        "User Experience",
      ],
    },
  ];

  const [initialInterestData, setInitialInterestData] = useState([]);
  // Search Logic
  // TODO: Later Search Logic
  // Handle Next
  const handleNext = async () => {
    try {
      // Construct the data object to send
      const dataToSend = initialInterestData.map((interest) => ({
        title: interest.title,
        selectedItems: interest.items
          .filter((item, index) => selectedItems[index])
          .map((item, index) => ({
            name: item,
            rating: ratings[index],
          })),
      }));
      console.log(dataToSend);
      // Make the HTTP request to the backend API
      const response = await axios.post(
        "http://172.20.10.3:8080/onboarding/v3",
        dataToSend
      );

      // Handle response as needed (e.g., show success message, navigate to next screen)
      console.log("Response from backend:", response.data);
      navigation.navigate("Career"); // Navigate to the next screen
    } catch (error) {
      // Handle error (e.g., show error message)
      console.error("Error sending data to backend:", error);
    }
  };

  return (
    // Margin Top is missing in this. i want same level of margin as my previous pages.
    <SafeAreaView style={{ flex: 1, alignItems: "center", marginTop: 40 }}>
      <TouchableOpacity
        onPress={() => {
          navigation.goBack();
        }}
        style={{
          position: "absolute",
          top: 3,
          left: 20,
          justifyContent: "center",
          alignItems: "center",
          flexDirection: "row",
        }}
      >
        <Icon name="chevron-left" size={24} color="#000" />
      </TouchableOpacity>
      <Text style={{ fontWeight: "bold", fontSize: 20, marginBottom: 5 }}>
        Areas of Interest
      </Text>
      <View style={{ width: 400, height: 1.5, backgroundColor: "#DBD4D4" }} />

      <FlatList
        data={interestData}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item }) => <InterestList data={item} />}
        ListHeaderComponent={() => (
          <>
            <Text
              style={{ fontSize: 17, marginTop: 10, paddingHorizontal: 15 }}
            >
              Select areas of interest and rate your expertise in each to
              receive personalized mentoring recommendations. Rate your
              expertise with the star system (1 - 5) to establish your
              proficiency.
            </Text>
            <Text
              style={{
                fontSize: 11,
                color: "#9C9C9C",
                textAlign: "left",
                marginTop: 10,
                paddingHorizontal: 15,
              }}
            >
              Your ratings are confidential and not displayed on your profile.
              We recommend selecting at least 3 options.
            </Text>

            <View
              style={{
                flexDirection: "row",
                alignItems: "center",
                backgroundColor: "#F1F1F3",
                width: "90%",
                height: 50,
                borderRadius: 20,
                marginTop: 15,
                paddingHorizontal: 20,
                borderColor: "#D9D9D9",
                borderWidth: 1,
                marginHorizontal: 15,
              }}
            >
              <Icon name="search" size={15} color="#9C9C9C" />
              <TextInput
                placeholder="Search Here"
                style={{ flex: 1, marginLeft: 10 }}
              />
            </View>
          </>
        )}
      />
      <View style={{ flexDirection: "row", height: 10, marginVertical: 10 }}>
        <NavigationLine active={true} />
        <NavigationLine active={true} />
        <NavigationLine active={true} />
        <NavigationLine active={false} />
        <NavigationLine active={false} />
      </View>
      <TouchableOpacity
        onPress={handleNext}
        style={{
          backgroundColor: "#09A1F6",
          padding: 10,
          borderRadius: 30,
          width: "90%",
          height: 50,
          justifyContent: "center",
          alignItems: "center",
          marginBottom: 10,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 24, fontWeight: "bold" }}>
          Next
        </Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
};

export default AreasOfInterest;