CSE 340: Web Backend Development

W04 Learning Activity: Updating Data

Overview

In previous activities you learned how to handle form submissions to insert data. In this activity, you will learn how to update existing data in your application.

Preparation Material

Creating a form to update existing data is very similar to the form for inserting data. The key difference is that the form fields are pre-populated with the current data, allowing users to make changes as needed. Then, when sending the data to the database, you use an update operation with the ID of the record, instead of an insert.

In this activity you will create a form to update existing organizations.

This update process will flow through each of the following steps:

Part 1: Display the edit form with existing data pre-populated
  1. On the organization details page, the user clicks a link to edit the organization, which contains the link /edit-organization/{id} where {id} is the id of the organization to edit (for example, /edit-organization/123 ).
  2. The server processes the /edit-organization route which calls the showEditOrganizationForm controller.
  3. The showEditOrganizationForm controller calls a model function to get the organization data by ID. (You will use your existing getOrganizationDetails function for this call).
  4. The existing getOrganizationDetails function retrieves the organization data from the database.
  5. The showEditOrganizationForm controller receives the organization data from the model function and passes it to the view edit-organization.ejs.
  6. The view edit-organization.ejs generates an HTML form pre-populated with the existing organization data.
Part 2: Process the edit form submission and update the database
  1. The user makes changes to the organization data in the edit-organization form and submits it.
  2. The form submission sends a POST request to the route route /edit-organization/{id}.
  3. The server processes the /edit-organization route which calls the processEditOrganization controller.
  4. The processEditOrganization controller extracts the updated organization data from the form submission. and calls a model function to update the organization data in the database.
  5. The updateOrganization function executes an SQL UPDATE statement to modify the existing organization record in the database based on the provided ID and updated data.
  6. After the update is complete, the processEditOrganization controller redirects the user to the organization details page with a flash message giving them the success message.
  7. The browser requests the organization details page, which gets the information from the database and displays it along with the flash message.

The following figures depicts this process visually. The first diagram shows part 1 of the process, which displays the edit form with the existing data prepopulated.

Update Organization Process Diagram Part 1
Part 1 Diagram

The second diagram shows part 2 of the process, which processes the form submission and updates the database.

Update Organization Process Diagram Part 2
Part 2 Diagram

Activity Instructions

Complete the following steps to create the edit organization view.

You can approach this task in a top-down manner, starting from what the user sees and work your way to the database. Or you could start with the database layer and work your back up, building and testing each function as you go.

This activity will follow the top-down approach, beginning with the client's request.

Add an Edit Link to the Organization Details page

In this step, you will add a link to the organization details page that allows the user to navigate to the edit organization view.

  1. Open your existing src/views/organization.ejs view file.
  2. Add an "Edit" link that links to the edit organization view. The link destination should be /edit-organization/{id}, where {id} is the ID of the organization to be updated (for example, /edit-organization/123).
Sample Code (Click to expand)
<p><a href="/edit-organization/<%= organizationDetails.organization_id %>">Edit Organization</a></p>

Add the route handler and controller for the Edit Organization form

In this step, you will create the route and controller function that displays the edit organization form.

  1. In your src/controllers/routes.js file, add a new GET route for /edit-organization/:id that calls a new controller function named showEditOrganizationForm.
    Sample Code (Click to expand)
    // Route to display the edit organization form
    router.get('/edit-organization/:id', showEditOrganizationForm);
    
  2. In your src/controllers/organizations.js file, create the showEditOrganizationForm function that retrieves the organization details by ID from the organization model (similar to the organization details controller) and passes that information to the edit-organization.ejs view.
    Sample Code (Click to expand)
    const showEditOrganizationForm = async (req, res) => {
        const organizationId = req.params.id;
        const organizationDetails = await getOrganizationDetails(organizationId);
    
        const title = 'Edit Organization';
        res.render('edit-organization', { title, organizationDetails });
    };
    
  3. Add the showEditOrganizationForm function to your list of exports.
  4. Return to the src/controllers/routes.js file and import the showEditOrganizationForm function.

Create the Edit Organization View

In this step, you will create the form for editing the organization.

  1. Create a new file named edit-organization.ejs in the src/views/ folder.
  2. As a starting point, copy and paste the content of your new-organization.ejs view into the new file.
  3. Change the form action from /new-organizationto be a new route: /edit-organization/{id} where id is the ID of the organization being updated.
  4. Pre-populate the form fields with the existing organization data using EJS syntax.
    • For the organization name input field, set the value attribute to <%= organizationDetails.name %>
    • For the organization description textarea, place <%= organizationDetails.description %> between the opening and closing <textarea> tags.
    • For the contact email input field, set the value attribute to <%= organizationDetails.contact_email %> .
    • Finally, add a new input field for the logo filename, and set the value attribute to <%= organizationDetails.logo_filename %> .
  5. Change the text of the submit button to "Update Organization".
Sample Code (Click to expand)

Your complete form may look something like this:

<%- include('partials/header') %>
<main>
    <h1><%= title %></h1>

 <form action="/edit-organization/<%= organizationDetails.organization_id %>" method="POST">
    <div class="form-group">
      <label for="name">Organization Name</label>
      <input
        type="text"
        id="name"
        name="name"
        value="<%= organizationDetails.name %>"
        maxlength="150"
        required
      />
    </div>

    <div class="form-group">
      <label for="description">Description</label>
      <textarea
        id="description"
        name="description"
        maxlength="500"
        required
      ><%= organizationDetails.description %></textarea>
    </div>

    <div class="form-group">
      <label for="contactEmail">Contact Email</label>
      <input
        type="email"
        id="contactEmail"
        name="contactEmail"
        maxlength="255"
        required
        value="<%= organizationDetails.contact_email %>"
      />
    </div>

    <div class="form-group">
      <label for="logoFilename">Logo Filename</label>
      <input
        type="text"
        id="logoFilename"
        name="logoFilename"
        maxlength="255"
        required
        value="<%= organizationDetails.logo_filename %>"
      />
    </div>


    <button type="submit">Update Organization</button>
  </form>

</main>
<%- include('partials/footer') %>

Stop here and test that your form is displaying correctly before moving on.

You should be able to visit the organization details page, click on the edit link, and see a form that is pre-populated with the organization's current details.

Add the route handler and controller to process the Edit Organization form submission

In this step, you will create the route and controller function that processes the edit organization form submission.

  1. In your src/controllers/routes.js file, add a new POST route for /edit-organization/:id that calls a new controller function named processEditOrganizationForm.
    Sample Code (Click to expand)
    // Route to handle the edit organization form submission
    router.post('/edit-organization/:id', processEditOrganizationForm);
    
  2. In your src/controllers/organizations.js file, create the processEditOrganizationForm function. It should do the following:
    1. Get the organization ID from req.params.id.
    2. Get the rest of the data (name, description, contactEmail, logoFilename) from req.body.
    3. Call a new model function named updateOrganization (which you will create in the next step) to update the organization in the database.
    4. Extract the updated organization data from the form submission using req.body and the organization ID from req.params.id.
    5. Call a new model function named updateOrganization (which you will create in the next step), passing all of the necessary parameters.
    6. After the update is complete, set a success flash message.
    7. Redirect the user back to the organization details page for that organization id.
    Sample Code (Click to expand)
    const processEditOrganizationForm = async (req, res) => {
        const organizationId = req.params.id;
        const { name, description, contactEmail, logoFilename } = req.body;
    
        await updateOrganization(organizationId, name, description, contactEmail, logoFilename);
        
        // Set a success flash message
        req.flash('success', 'Organization updated successfully!');
    
        res.redirect(`/organization/${organizationId}`);
    };
    
  3. Add the processEditOrganizationForm function to your list of exports.
  4. Return to the src/controllers/routes.js file and import the processEditOrganizationForm function.

Create the updateOrganization model function

In this step, you will create the model function that updates the organization in the database.

  1. In your src/models/organizations.js file, create a new function named updateOrganization that takes the following parameters: id, name, description, contactEmail, logoFilename.
  2. Inside the function, create an SQL UPDATE statement that updates the organization record with the provided ID, setting the name, description, contact email, and logo filename to the new values.
  3. Execute the SQL statement using your database connection.
  4. Sample Code (Click to expand)
    const updateOrganization = async (organizationId, name, description, contactEmail, logoFilename) => {
      const query = `
        UPDATE organization
        SET name = $1, description = $2, contact_email = $3, logo_filename = $4
        WHERE organization_id = $5
        RETURNING organization_id;
      `;
    
      const query_params = [name, description, contactEmail, logoFilename, organizationId];
      const result = await db.query(query, query_params);
    
      if (result.rows.length === 0) {
        throw new Error('Organization not found');
      }
    
      if (process.env.ENABLE_SQL_LOGGING === 'true') {
        console.log('Updated organization with ID:', organizationId);
      }
    
      return result.rows[0].organization_id;
    };
    
  5. Add the updateOrganization function to your list of exports.
  6. Return to your src/controllers/organizations.js file and import the updateOrganization function.

Stop here and test that your update functionality is working correctly before moving on.

You should be able to visit the organization details page, click on the edit link, make changes in the form, submit it, and see the updated details reflected on the organization details page along with a success flash message.

Add Validation

In this step, you will add validation to ensure that the data being submitted in the edit organization form is valid before updating the database.

Because the validation rules for editing an organization are the same as for creating a new one, you can reuse the validation logic you implemented earlier.

  1. In your src/controllers/routes.js file, update the POST route for /edit-organization/:id to include the existing validation middleware you created for new organizations.
    Sample Code (Click to expand)
    // Route to handle the edit organization form submission
    router.post('/edit-organization/:id', organizationValidation, processEditOrganizationForm);
    
  2. In your src/controllers/organizations.js file, update the processEditOrganizationForm function to check for validation errors using validationResult(req).
    • If there are validation errors, redirect back to the /edit-organization/:id page.
    • If there are no validation errors, proceed with updating the organization as before.
    Sample Code (Click to expand)

    You can can something like the following to your processEditOrganizationForm function:

    // Check for validation errors
    const results = validationResult(req);
    if (!results.isEmpty()) {
        // Validation failed - loop through errors
        results.array().forEach((error) => {
            req.flash('error', error.msg);
        });
    
        // Redirect back to the edit organization form
        return res.redirect('/edit-organization/' + req.params.id);
    }
    

Next Step

Complete the other Week 04 Learning Activities

After you have completed all the learning activities for this lesson, return to Canvas to submit a quiz.

Other Links: