> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prequel.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Building an "Edit Destination" connection form

> Build a dynamic "Edit Destination" form to allow your users to edit, test, and update their destinations.

<Steps>
  <Step title="Get the destination to edit">
    Use the `useGetDestinationsForRecipient` hook to get a list of destinations and select the destination to edit. The example below uses the destination ID from the url to select the `currentDestination`, but there are many other viable solutions to obtain it.

    ```tsx title="Select destination to edit" icon="react" expandable theme={null}
    const destinationID = "X" // Obtain destination ID by your preference
    const [destinations, setDestinations] = useState<ExistingDestination[]>();
    const [currentDestination, setCurrentDestination] = useState<ExistingDestination>();
    const getDestinations = useGetDestinations(
      fetchToken,         // fetchToken implementation, takes no parameters
      "app.example.co", 	// the origin of your React app (used to allow CORS),
      PREQUEL_HOST 				// Optional (default api.prequel.co): the host url of your Prequel API
    );

    // Fetch destinations in useEffect elided...

    useEffect(() => {
      setCurrentDestination(destinations.find(({ id }) => id === destinationID);
    }, [destinations, destinationID])
    ```
  </Step>

  <Step title="Render the form with existing destination values">
    This step can be done by amending your "Create Destination" form to optionally accept a destination, or you can build a separate form implementation that strictly accepts a destination or destination ID.

    After selecting the destination to edit, populate the form with that existing destination's values. This can be done by leveraging the `prepareDestinationFromExisting` helper function and the `setDestination` function returned from the `useDestination` hook.

    ```tsx title="EditDestinationForm" icon="react" expandable theme={null}
    const EditDestinationForm = () => {
      // Destination selection code (above) elided
      const [destination, setDestination] = useDestination();
      const destinationForm = useDestinationForm(
        destination,
        PREQUEL_ORG_ID, // the UUID for your organization in Prequel
        {
          includeInternalFields: true,	// Optional (default false): hide any non-user facing fields like "name"
          host: PREQUEL_HOST,		        // Optional (default api.prequel.co): the host url of your Prequel API
      );
      const updateDestination = useUpdateDestination(
        fetchTokenWithDestination,  // fetchToken implementation, takes an ExistingDestination
        "app.example.co", 					// the origin of your React app (used to allow CORS)
        PREQUEL_HOST 							  // the host url of your Prequel API
      );

      useEffect(() => {
        if (currentDestination) {
          const converted = prepareDestinationFromExisting(currentDestination);
          setDestination(converted); // This line is what will populate the existing values in the destination
        }
      }, [setDestination, currentDestination]);

      // This is the PreparedDestination you can pass to testExistingConnection and updateDestination
      const preparedDestination = useMemo(
        () => prepareDestinationWithForm(destination, destinationForm),
        [destination, destinationForm]
      );

      // If desired, include a loading spinner if values are undefined
      return (
        <Form ref={formRef} className="d-flex flex-column" onSubmit={onSubmit}>
          {destinationForm.map((section) => (
            <Fragment key={section.id}>
              <Form.Group>
            		{/* Render the section title and subtitle... */}
                {section.fields.map((field) => {
                  {/* Render the field with destination value... */}
                })}
              </Form.Group>
            </Fragment>
          ))}
          <Button type="submit">Submit form</Button>
        </Form>
      );
    }
    ```

    ### Non-required secret fields

    `ExistingDestination` objects fetched from Prequel will not include secret values (e.g. passwords, service account keys) for security reasons. When populating the form with existing values, those fields will remain empty. Though the `Form` object has them labeled as `required`, you should set those fields as optional in the form and only send *updated* secret values to the test and edit functions. If you do not include a secret value, Prequel will look up the destinations existing secret value when testing the connection.
  </Step>

  <Step title="Test and update destinations">
    Once your form is properly populating and updating values on the destination, you should add functionality to test the destination. It's recommended that you only allow users to update destinations with values that are connecting successfully. You can leverage the `useTestExistingConnection` hook to add this functionality.

    ```tsx title="TestConnectionComponent" icon="react" expandable theme={null}
    const TestConnectionComponent = ({ destination, preparedDestination }) => {
    	const [testRunning, setTestRunning] = useState(false);
      const [testResult, setTestResult] = useState<string | null>(null);
      const testExistingConnection = useTestExistingConnection(
        fetchTokenWithDestination,  // fetchToken implementation, takes an ExistingDestination
        "app.example.co", 					// the origin of your React app (used to allow CORS)
        PREQUEL_HOST 							  // the host url of your Prequel API
      );

      async function testDestinationConnection() {
        setTestRunning(true);
        setTestResult("Testing new connection...");
        const { data, message } = await testExistingConnection(destination, preparedDestination);
        if (data?.status === "success") {
          setTestResult("Connection test successful.");
        } else {
          setTestResult(message);
        }
        setTestRunning(false);
      }

      return (
        <div>
        {/* Render connection information as desired... */}
        </div>
      )
    }
    ```
  </Step>
</Steps>
