3

I want to create a form that creates a card that I can edit. Whenever I try to click on the edit button to update the card, the information that was made doesn't transfer over into the new screen. When I try to edit it anyway, I get a 400 message saying

Failed to load resource: the server responded with a status of 400 (Bad Request)

I tried changing the dates to integers and Floats, but nothing. When I try to change the ID to experienceID in the Experience page variable under UseParams, I get more error messages. I have checked and double-checked my mutations, resolvers, typeDefs, etc., but I still can't seem to get it working. I also tried using AI to fix the problem, and it suggested that I change all of my dates from strings to integers, but that didn't help with my 'update a form' problem..

I got a correction request to state what I want (always have been on the first line), show the shortest amount of code (I did that), and state the problem (I did).

ExperiencePage.js

import { useMutation, useQuery } from "@apollo/client";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { GET_EXPERIENCE } from "../graphql/queries/experience.query.js";
import { UPDATE_EXPERIENCE } from "../graphql/mutations/experience.mutations.js";
import toast from "react-hot-toast";

const ExperiencePage = () => {
  const { id } = useParams();
  const { loading, data} = useQuery(GET_EXPERIENCE, {
    variables: { id: id },
  });

  console.log("UseQuery:", data)

  const [updateExperience] = useMutation(UPDATE_EXPERIENCE);

  const [formData, setFormData] = useState({
    description: data?.experience?.description || "",
    title: data?.experience?.title || "",
    type: data?.experience?.type || "",
    startDate: data?.experience?.startDate || "",
    endDate: data?.experience?.endDate || "",
  });

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      await updateExperience({
        variables: {
          input: {
            ...formData,
            experienceID: id,
            startDate: formData.startDate ? new Date(formData.startDate).getTime() : null,
            endDate: formData.endDate ? new Date(formData.endDate).getTime() : null,
          },
        },
      });
      toast.success("Experience updated successfully");
    } catch (error) {
      toast.error(error.message || "Update failed");
    }
  };

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFormData((prevFormData) => ({
      ...prevFormData,
      [name]: value,
    }));

    console.log(formData)
  };

  useEffect(() => {
    if (data && data.experience) {
      setFormData({
        description: data.experience.description || "",
        title: data.experience.title || "",
        type: data.experience.type || "",
        startDate: data.experience.startDate
          ? new Date(Number(data.experience.startDate)).toISOString().slice(0, 10)
          : "",
        endDate: data.experience.endDate
          ? new Date(Number(data.experience.endDate)).toISOString().slice(0, 10)
          : "",
      });
    }
  }, [data]);

  if (loading) return <p>Loading...</p>

  return (
    <div>
      {/*  */}
      <form className="w-full max-w-lg flex flex-col gap-5 px-3" onSubmit={handleSubmit}>
        <div className="space-y-12">
          <div className="border-b border-gray-900/10 pb-12">
            <h2 className="text-base/7 font-semibold text-gray-900">Update Experience Form</h2>
         
            <div className="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
              <div className="sm:col-span-4">
                <label htmlFor="title" className="block text-sm/6 font-medium text-gray-900">
                  Title
                </label>
                <div className="mt-2">
                  <div className="flex items-center rounded-md bg-white pl-3 outline-1 -outline-offset-1 outline-gray-300 focus-within:outline-2 focus-within:-outline-offset-2 focus-within:outline-indigo-600">
                    <input
                      className="block min-w-0 grow py-2 pr-3 pl-1 text-base text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm/6"
                      id="title"
                      name="title"
                      type="text"
                      placeholder="Title"
                      value={formData.title}
                      onChange={handleInputChange}
                    />
                  </div>
                </div>
              </div>

              <div className="col-span-full">
                <label htmlFor="description" className="block text-sm/6 font-medium text-gray-900">
                  Description
                </label>
                <div className="mt-2">
                  <textarea
                    id="description"
                    name="description"
                    rows={3}
                    className="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
                    placeholder="Write a description of your experience: Awards, goals achieved, lessons learned, etc.  Make sure to use keywords you want to be analyzed."
                    value={formData.description}
                    onChange={handleInputChange}
                  />
                </div>

                <div className="sm:col-span-3">
                  <label htmlFor="type" className="block text-sm/6 font-medium text-gray-900">
                    Type
                  </label>
                  <div className="mt-2 grid grid-cols-1">
                    <select
                      className="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white py-1.5 pr-8 pl-3 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
                      id="type"
                      name="type"
                      onChange={handleInputChange}
                      value={formData.type}
                    >
                      <option value="">Type</option>
                      <option value="education">Education</option>
                      <option value="employment">Employment</option>
                      <option value="internship">Internship</option>
                      <option value="volunteer">Volunteer</option>
                    </select>
                  </div>
                </div>

                <div className="w-full flex-1">
                  <label className="block text-sm/6 font-medium text-gray-900" htmlFor="startDate">
                    Start Date
                  </label>
                  <input
                    type="date"
                    name="startDate"
                    id="startDate"
                    className="block min-w-0 grow py-1.5 pr-3 pl-1 text-base text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm/6"
                    placeholder="Select start date"
                    value={formData.startDate}
                    onChange={handleInputChange}
                  />
                  <label className="block text-sm/6 font-medium text-gray-900" htmlFor="endDate">
                    End Date
                  </label>
                  <input
                    type="date"
                    name="endDate"
                    id="endDate"
                    className="block min-w-0 grow py-1.5 pr-3 pl-1 text-base text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm/6"
                    placeholder="Select end date"
                    value={formData.endDate}
                    onChange={handleInputChange}
                  />
                </div>

                <button
                  className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-xs hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
                  type="submit"
                >
                  Update Experience
                </button>
                <button type="button" className="text-sm/6 font-semibold text-gray-900">
                  Cancel
                </button>
              </div>
            </div>
          </div>
        </div>
      </form>
    </div>
  );
};

export default ExperiencePage;

Query, Mutation, Resolve, TypeDef

Query:

export const GET_EXPERIENCE = gql`
    query GetExperience($id: ID!) {
        experience(experienceID: $id) {
            _id
            title
            type
            description
            startDate
            endDate
        }
            user {
                email
            }
        }
    
`;

Mutation:
export const UPDATE_EXPERIENCE = gql`
    mutation UpdateExperience($input: UpdateExperienceInput!) {
        updateExperience(input: $input) {
            experienceID
            title
            type
            description
            startDate
            endDate
        }
    }
`;


Resolvers:

updateExperience: async (_, { input }) => {
  try {
    const updatedExperience = await Experience.findByIdAndUpdate(input.experienceID, input, {
      new: true,
    });
    return updatedExperience;
  } catch (err) {
    console.error("Error updating Experience:", err);
    throw new Error("Error updating Experience");
  }
},

TypeDef:

type Experience {
    _id: ID!
    userId: ID!
    description: String!,
    title: String!,
    type: String,


    startDate: Date,
    endDate: Float,
}

type Query {
    experiences: [Experience!]
    experience(experienceID: ID!): Experience
}

type Mutation {
    addExperience(input: AddExperienceInput!): Experience!
    updateExperience(input: UpdateExperienceInput!): Experience!
    deleteExperience(experienceID: ID!): Experience!
}

input AddExperienceInput {
    description: String!,
    title: String!,
    type: String,
    startDate: Date,
    endDate: Date,
}

input UpdateExperienceInput {
    experienceID: ID!
    description: String,
    title: String,
    type: String,
    startDate: Date,
    endDate: Date,
}
1
  • 3
    What's in the response body for the 400 status response? Commented Aug 13 at 5:50

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.