Polling Webs App - Deleting Options & Updating Results
Like most people the holiday season is a rather busy time, this meant that for several weeks I made no progress when it came to this app. Starting back up after the holiday season has always been rather slow for me, but I am hoping to pick up where I left off. Similar to my last update I will be doing a fairly small update to the app adding the features to delete an option and update a result.
Deleting Options
Deleting Option Service
Starting off with with deleting an option add a new service file named "deleteOptions.ts" in the "services/options" directory. As with all of the other options services import the following "eq" from "drizzle-orm", "db" from "drizzle.ts", and "options" from "schema.ts". The "deleteOptions.ts" service has an export function was created this time called "deleteOptionById". The function queries the database to locate a poll with a matching provided ID then deletes it, since the schema has cascading configured it will also delete options and responses that match the poll id.
import { eq } from "drizzle-orm";
import { db } from "../../db/drizzle";
import { options } from "../../db/schema";
export const deleteOptionById = async (optionID: any) => {
const deleteOption = await db
.delete(options)
.where(eq(options.id, optionID))
return deletePoll
}
deleteOptions.ts
Deleting Option Controller
Moving on from the deleting options service into the delete options controller. In the "options.controller.ts" file import the "deleteOptionById", then create an export function called "deleteOptionByIdController". The export function has a try/catc block that uses the "optionID" that was retrieved from the request's query parameters and validates it. If the id is valid it moves on from there and calls the delete option by id function and takes the option id as its argument, if successful a success message is returned, while the catch block handles the any errors.
import { deleteOptionById } from "../services/polls/deleteOptions";
export const deleteOptionByIdController = async (req: Request, res: Response) => {
try {
const { optionID } = req.query;
if (!optionID) {
return res.sendStatus(400);
}
const poll = await deleteOptionById(OptionID);
return res.status(200).send("Option was deleted");
} catch (error) {
console.error(error);
return res.sendStatus(400);
}
}
Modified option controller
Deleting Option Router
Lastly for delete option a new route was made, the route's prefix for the route is "/delete-by-id" and the HTTP method is a DELETE. Import from the options controller "deleteOptionByIdController" and have the newly created route use the imported function.
import { ..., deleteOptionByIdController } from "../controllers/option.controller";
pollRouter.delete("/delete-by-id", deleteOptionByIdController);
delete option route
Updating Results
Get Result By ID Service
Two additional features need to be made in order to make the update results work as I expect it to, the first being getting the current result total and updating the results with the incoming increase. In "getResults.ts" add a new export function called "getResultById". It takes a parameter called resultID checks if there is a result with a matching id and returns the existing total.
export const getResultById = async (resultID: any) => {
const getResultTotal = await db
.select({
total: results.total
})
.from(results)
.where(eq(results.id, resultID))
return getResultTotal
}
Get Results By ID
Update Results Service
The second part needed to update the results is actually updating the result in the database. In the "services/options" directory add a file called "updateOptions.ts". Import "eq" from "drizzle-orm", "db" from "drizzle.ts", and its schema "results" from "schema.ts". Create an export function called "updateResultById", it takes 3 arguments, the result id, the amount to increase by, and the current total. Assign a new variable named "newTotal" that is equal to the current total and the increase amount. Query the database using the result id argument and set the current total to the new total.
import { eq } from "drizzle-orm";
import { db } from "../../db/drizzle";
import { results } from "../../db/schema";
export const updateResultById = async (resultID: any, increase: number, total: any) => {
const newTotal = total + increase
const updateResult = await db
.update(results)
.set({
total: newTotal
})
.where(eq(results.id, resultID))
return updateResult
}
updateResults.ts
Update Results Controller
Now it's time to have the two services work together in order to update the result. Add a new file in the "controllers" directory called "results.controller.ts". This file imports "Request" and "Response" from "express", "updateResultById" from "updateResults.ts", and "getResultById" from "getResults.ts". Like other controller functions it uses a try/catch block, within the try portion begin by destructing "resultID" and "increase" from the request body. Assign a variable that collects the result from "getResultById". Call the update result function with acquired total, result id, & increase.
import { Request, Response } from "express";
import { updateResultById } from "../services/results/updateResults";
import { getResultById } from "../services/results/getResults";
export const updateResultByIdController = async (req: Request, res: Response) => {
try {
const { resultID, increase } = req.body;
if (!resultID) {
return res.sendStatus(400);
}
const total = await getResultById(resultID);
const result = await updateResultById(resultID, increase, total[0].total);
return res.status(200).send("Result was updated");
} catch (error) {
console.error(error);
return res.sendStatus(400);
}
}
results.controller.ts
Update Results Router
Next, for update results is to configure a router for the options. Import "Router" from "express" to setup the router and "updateResultByIdController" from "results.controller.ts". Create a const called "resultRouter" that calls the Router function. Define a new route with a PATCH method that has a prefix of "/update-by-id" and uses the "updateResultByIdController". In "app.ts" import the router and use it in a "/results" route.
import { Router } from "express";
import { updateResultByIdController } from "../controllers/results.controller";
export const resultRouter = Router();
resultRouter.patch("/update-by-id", updateResultByIdController);
results.routes.ts
Conclusion
This was a fairly simple update that built upon my previous work. This was the first update that allowed my app to be able to have options my independent from polls. As this project continues more combined and independent systems will need to be developed, this was, but a brick in the foundation that will continue to grow.
If you would like to check out the code or us it for yourself: Github Link
If this blog was helpful to you please consider subscribing.