Uploading and saving data to an object in FaunaDB using React hook forms

I am currently facing an issue with uploading/saving data to an object in FaunaDB. Specifically, I am trying to upload a string to a jobProfile object:

data: {
 "jobProfile": {
    "image": ""
    "coverImage": ""
 }
}

However, when I attempt to upload the strings using the submit button, they are getting saved in the root like this:

data: {
  "image": ""
  "coverImage": ""
}

In my main component, I have integrated react-hook-forms where default values are fetched from userData obtained via useSWR through a prop:

import { useForm } from "react-hook-form"

import ImageInput from "./ImageInput"

export default function Inputs({ userData }) {
  const defaultValues = {
    image: userData?.jobProfile?.image ? userData?.jobProfile?.image : "",
    coverImage: userData?.jobProfile?.coverImage ? userData?.jobProfile?.coverImage : ""
  }

  const { register, handleSubmit } = useForm({ defaultValues })

  const handleUpdateUser = async (data) => {
    const { image, coverImage } = data
    try {
      await fetch("/api/updateProfile", {
        method: "PUT",
        body: JSON.stringify({
          image, coverImage
        }),
        headers: {
          "Content-Type": "application/json",
        },
      })
      alert(`submitted data: ${JSON.stringify(data)}`)
    } catch (err) {
      console.error(err)
    }
  }

  return (
    <form onSubmit={handleSubmit(handleUpdateUser)}>
      <div className="py-4">
        <ImageInput register={register} />
      </div>
      <button type="submit">Update</button>
    </form>
  )
}

Below is the component ImageInput.jsx imported within the main component. This component includes input fields for image and coverImage:

//ImageInput.jsx
export default function ImageInput({ register }) {
  return (
    <div className="grid gap-4">
      <div>
        <label
          htmlFor="company-website"
          className="block text-sm font-medium text-gray-700"
        >
          Profilbillede
        </label>
        <div className="relative mt-1 rounded-md shadow-sm">
          <div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
            <span className="text-gray-500 sm:text-sm">https://</span>
          </div>
          <input
            type="text"
            name="company-website"
            id="company-website"
            className="block w-full rounded-md border-gray-300 pl-16 focus:border-indigo-500 focus:ring-indigo-500 sm:pl-14 sm:text-sm"
            placeholder="www.example.com/profile/avatar"
            {...register("jobProfile.image", {})}
          />
        </div>
        <p className="mt-2 text-sm text-gray-500" id="email-description">
          Indsæt billede URL (link) fra eksempelvis Facebook eller LinkedIn.
        </p>
      </div>

      <div>
        <label
          htmlFor="company-website"
          className="block text-sm font-medium text-gray-700"
        >
          Coverbillede
        </label>
        <div className="relative mt-1 rounded-md shadow-sm">
          <div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
            <span className="text-gray-500 sm:text-sm">https://</span>
          </div>
          <input
            type="text"
            name="company-website"
            id="company-website"
            className="block w-full rounded-md border-gray-300 pl-16 focus:border-indigo-500 focus:ring-indigo-500 sm:pl-14 sm:text-sm"
            placeholder="www.example.com/profile/avatar"
            {...register("jobProfile.coverImage", {})}
          />
        </div>
        <p className="mt-2 text-sm text-gray-500" id="email-description">
          Indsæt billede URL (link) fra eksempelvis Facebook eller LinkedIn.
        </p>
      </div>
    </div>
  )
}
//updateProfile.js
import { updateProfileInfo } from "@/utils/Fauna"
import { getSession } from "next-auth/react"

export default async (req, res) => {
  const session = await getSession({ req })
  if (!session) return res.status(401)

  const userId = session.user.id
  if (req.method !== "PUT") {
    return res.status(405).json({ msg: "Method not allowed" })
  }

  const { image, coverImage } =
    req.body
  try {
    const updated = await updateProfileInfo(
      userId,
      image,
      coverImage
    )
    return res.status(200).json(updated)
  } catch (err) {
    console.error(err)
    res.status(500).json({ msg: "Something went wrong." })
  }
  res.end()
}
//fauna.js
import * as Fauna from "faunadb"

const faunaClient = new Fauna.Client({
  secret: process.env.FAUNA_ADMIN_SECRET,
  scheme: "https",
  domain: "db.eu.fauna.com",
  port: 443,
})
const q = Fauna.query

const getUserById = async (id) => {
  const userData = await faunaClient.query(
    q.Get(q.Ref(q.Collection("users"), id))
  )
  delete userData.data.emailVerified
  delete userData.data.createdAt
  delete userData.data.updatedAt
  delete userData.data.ssn
  return userData.data
}

const updateProfileInfo = async (
  userId,
  image,
  coverImage
) => {
  return await faunaClient.query(
    q.Update(q.Ref(q.Collection("users"), userId), {
      data: {
        image,
        coverImage
      },
    })
  )
}

module.exports = {
  getUserById,
  updateProfileInfo
}

I would appreciate your help in identifying what I might be doing incorrectly.

Answer №1

Ensure that in your updateProfileInfo function within the fauna.js file, you include:

data: {
  jobProfile: {
    image,
    coverImage
  }
},

Instead of:

data: {
  image,
  coverImage
},

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display the div element only when the mouse is hovering over the button

I need a hidden text inside a div that will only appear when the mouse pointer is hovering over a specific button. Here is my current code: // Show help-text on hover $("#help-container") .mouseover(function(e) { $(this).find("#help-t ...

Messages in a designated channel that are automatically erased

I have set up a suggestion channel where users can only post links, and the bot will react based on what they post. I've managed to make the bot automatically react to links, but I'm struggling to get it to delete anything that is not a link. I w ...

What is the reason behind the restriction on using capital letters in React project names?

When attempting to create a new project "newRecipeApp" in React, I encountered the following message: npx: installed 91 in 29.359s Could not create a project called "newRecipeApp" because of npm naming restrictions: * name can no longer contain capital ...

What are the steps to turn off the rule .MuiInputBase-inputType-121 in Material UI TextField for email input field because of a display problem?

Here is a snippet of JSX code: import TextField from '@material-ui/core/TextField/TextField'; <Col xs={6}> <TextField pattern=".{3,}" name="fullName" ...

Content within a Row of a Data Table

Hello! I am just starting to learn JavaScript and jQuery. Can you help me with an issue I am experiencing? Basically, I have a table and I need to identify which tr contains a td with the text "Weekly", "Daily", or "Monthly". Once I locate that specific t ...

I need some help with adjusting the number of rows shown per page in MaterialReactTable

I've been utilizing MaterialReactTable and my goal is to display only 5 items on each pagination page. Despite setting muiTablePaginationProps, I still see 10 items per page. How can I resolve this issue? <MaterialReactTable columns={columns} ...

Retrieving Vue data from parent components in a nested getter/setter context

<template> <div id="app"> {{ foo.bar }} <button @click="meaning++">click</button> <!--not reactive--> <button @click="foo.bar++">click2</button> </div> </templ ...

The Cross-Origin Resource Sharing request using the PUT method has been denied due to restrictions set by the

I am currently using CORS requests to communicate between my client and server located on different domains. I have configured my Apache HTTP server to use SSL in the following manner: // Utilizing AJAX withCredentials=true (sending cookies, allowing SSL ...

Show the nested div when hovering over the containing div using JavaScript

I have a situation where I have multiple divs within a parent div, all using the same class. Here is an example: <div class="deck-content"> <div class="deck-box">TEST< <div class="deck-hidden">< <span class= ...

Modify a necessary input value using jQuery or JavaScript

I am looking to update the required value of an input based on a checkbox selection. Here is my current code, any assistance would be appreciated. <input type="checkbox" id="no_land_line" name="no_land_line" value=""> // check this box if no land li ...

What is the best way to retain data after clicking a button?

I am facing an issue where I need to figure out how to add information to a new page when a button is clicked. For example, let's say I have an "add to cart" button and upon clicking it, I want to store some data. How can I achieve this functionality? ...

The window.open function is creating a new tab using the specified origin or URL

I have a button within an iframe on the webpage "loclahost:3000". When this button is clicked, it should open a new tab with the URL "www.google.com". However, instead of opening the desired URL, the new tab opens with the following incorrect URL: "http:// ...

angular failure to assign a variable to $scope

When communicating with the Node server, I am able to receive a response message in the controller. However, there seems to be an issue with assigning it properly. .controller('someCtrl', function(exportExcel){ $scope.clickEvent = function() ...

Updates to $scope are not reflecting in the application

My input includes a datalist that is populated by an angular get request as the page loads. <input list="data" /> <datalist id="data"> <option ng-repeat="item in items" value="{{item.data}}"> </datalist> The $http call is straig ...

Selecting a single checkbox automatically selects all other checkboxes

Is there a way to automatically check all other checkboxes if one checkbox is checked? Here's the code snippet I have: <tr> <td class="small"><asp:CheckBox ID="chkReportModuleName" runat="server" name="report"></asp:CheckBox& ...

The concept of setTimeout and how it affects binding in JavaScript

I have limited experience with jquery, mainly using it for toggling classes. However, I will do my best to explain my issue clearly. I have three div elements and when one is clicked, the other two should rotate 90 degrees and then collapse to a height of ...

Tips for fixing the error "TypeError: useOptimistic is only functional in Client Components" when using the use client directive in Next.js

After following the error message's suggestion and adding the "use client" directive at the top of my file, I'm still running into an issue while trying to utilize the useOptimistic hook in my Next.js page. The error message reads as follows: Typ ...

Tips for creating a textarea element that resembles regular text format

I am working on creating an HTML list that allows users to edit items directly on the page and navigate through them using familiar keystrokes and features found in word processing applications. I envision something similar to the functionality of To achi ...

What is the best way to omit the final item in a v-for loop?

I'm just starting out with JavaScript and learning about JS frameworks. I recently came across this snippet of Vuejs code: <div v-for="coefficient in coefficients" class="coefficient"> <div> <span class="name">name:{{coe ...

JavaScript Lint Warning: Avoid declaring functions inside a loop - unfortunately, there is no way to bypass this issue

In my React JS code snippet, I am attempting to search for a value within an object called 'categories' and then add the corresponding key-value pair into a new map named sortedCategories. var categoriesToSort = []; //categoriesToSort contains ...