Message!
This is an old work, for updated version please visit Updated FastAPI WebApp Course
In the last 5-6 articles we have used 'Forms' extensively, but there is a serious problem with the Form-based implementation. We already have apis to get Job post, create, update and delete. Still, we are re-writing most of the code and not respecting the DRY(Don't Repeat Yourself) principle.
In this article, we will see how we can simply delete a job post using some javascript in our code. This might be new for some of you, So, we feel uncomfortable at first but if you understand this logic, You would love it. Enough talk let's gets started. Add the following code in webapps > jobs > route_jobs.py
#...
@router.get("/delete-job/")
def show_jobs_to_delete(request: Request, db: Session = Depends(get_db)):
jobs = list_jobs(db=db)
return templates.TemplateResponse(
"jobs/show_jobs_to_delete.html", {"request": request, "jobs": jobs}
)
Done, This would render our template with all the jobs in our database and we will be deleting jobs by calling our API using fetch api of in Javascript. Let's add the below template code in templates > jobs > show_jobs_to_delete.html
{% extends "shared/base.html" %}
{% block title %}
<title>Delete Jobs</title>
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h1 class="display-5 text-center text-danger mb-3">Delete Jobs</h1>
</div>
<div id="result" class="text-danger text-bold lead"></div>
</div>
<div class="row">
<table class="table">
<thead>
<tr>
<th scope="col">Sr. No.</th>
<th scope="col">Title</th>
<th scope="col">Company</th>
<th scope="col">Company URL</th>
<th scope="col">Location</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{% for job in jobs %}
<tr>
<th scope="row">{{loop.index}}</th>
<td>{{job.title}}</td>
<td>{{job.company}}</td>
<td>{{job.company_url}}</td>
<td>{{job.location}}</td>
<td><button class="btn btn-danger btn-sm" onclick="delete_job({{job.id}})">Delete</button></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
function delete_job(id){
fetch('/jobs/delete/'+id,{
method:'DELETE',})
.then(response => response.json())
.then(document.getElementById('result').innerHTML = "Refreshing...")
.then(data => document.getElementById('result').innerHTML = data.detail);
}
</script>
{% endblock %}
In the block named contents
we have simply tried to list the jobs in a tabular form and nothing more. We also have a div named result where we would be passing the messages received by our api. Whether it is a success message or some error. We would append it to the result div dynamically using Javascript.
The main logic is in scripts
block, Here we have a delete_job function which is called with the id of job When the corresponding delete button is clicked. We make a DELETE request to our own api (See its implementation). Now it is the responsibility of our api to check if the user is authenticated and authorized to delete the job post and finally delete the Job. Whatever response we receive from our api, we simply show it to the user in result div.
One more thing, make sure our api is returning a detail
key in the response instead of the msg key, Because our javascript is extracting detail from api response. So, in the apis > version1 > route_jobs.py update this line:
#return {"msg": "Successfully deleted."} remove it
return {"detail": "Successfully deleted."} #add this line
Time to test our implementation: Visit http://127.0.0.1:8000/delete-job/
Final git commit: https://github.com/nofoobar/JobBoard-Fastapi/commit/6edf54113c4630b8b5fe2018078a8647136395db
Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.
We know, we might make it hard for you but definitely worth the efforts.
© Copyright 2022-23 Team FastAPITutorial