Building an "Edit Destination" Connection Form

This guide demonstrates building a dynamic "Edit Destination" form to allow your users to edit, test & update their destinations.

Step 1: 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.

const destinationID = "X" // Obtain destination ID from URL
const [destinations, setDestinations] = useState<ExistingDestination[]>();
const [currentDestination, setCurrentDestination] = useState<ExistingDestination>();
const getDestinations = useGetDestinationsForRecipient(
  fetchTokenRecipient,  // fetchToken implementation, takes a recipient ID
  "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 useEffect elided...

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

Step 2: 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.

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
    true, 					// Optional (default false): hide any non-user facing fields like "name"
    PREQUEL_HOST,		// Optional (default api.prequel.co): the host url of your Prequel API
  );
  const createDestination = 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 3: 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.

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) {
      setTestResult("Connection test successful.");
    } else {
      setTestResult(message);
    }
    setTestRunning(false);
  }
  
  return (
    <div>
    {/* Render connection information as desired... */}
    </div>
  )
}

What’s Next

To learn how add support for users to delete existing destinations, see the next tutorial.