I am currently developing a Single Page Application (SPA) using Rails for the backend and JavaScript for the frontend. When I submit the initial form to create a Resource, it shows up on the page immediately upon pressing the submit button. However, when I try to edit the Resource, I have to refresh the page to see the updated information.
Is there a way to make sure that the updated Resource is displayed on the page without needing to refresh?
index.js
const materialIndex = "http://localhost:3000/api/v1/materials"
const categoryIndex = "http://localhost:3000/api/v1/categories"
document.addEventListener('DOMContentLoaded', () => {
getMaterials()
const createMaterialForm = document.querySelector("#create-material-form")
createMaterialForm.addEventListener("submit", (e) => createFormHandler(e))
const materialContainer = document.querySelector('#material-container')
materialContainer.addEventListener('click', e => {
//debugger
const id = parseInt(e.target.closest('[data-id]').dataset.id)
const material = Material.findById(id)
document.querySelector('#edit-material').innerHTML = material.renderPatchForm()
console.log(material)
})
document.querySelector('#edit-material').addEventListener('submit', e => updateForm(e))
})
function getMaterials() {
fetch(materialIndex) //get request
.then(response => response.json())
.then(materials => {
materials.data.forEach(material => {
let newMaterial = new Material(material, material.attributes)
document.querySelector('#material-container').innerHTML += newMaterial.renderMaterialCard()
})
})
}
function createFormHandler(e) {
e.preventDefault()
const nameInput = document.querySelector('#input-name').value
const descriptionInput = document.querySelector('#input-description').value
const urlInput = document.querySelector('#input-url').value
const categoryId = parseInt(document.querySelector('#categories').value)
postFetch(nameInput, descriptionInput, urlInput, categoryId)
}
function updateForm(e) {
e.preventDefault()
const id = parseInt(e.target.closest('[data-id]').dataset.id)
const material = Material.findById(id)
const name = e.target.querySelector('#input-name').value
const description = e.target.querySelector('#input-description').value
const url = e.target.querySelector('#input-url').value
const category_id = parseInt(e.target.querySelector('#categories').value)
patchMaterial(material, name, description, url, category_id)
}
function postFetch(name, description, url, category_id) {
const bodyData = {name, description, url, category_id}
fetch(materialIndex, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(bodyData)
})
.then(response => response.json())
.then(material => {
const materialData = material.data
let newMaterial = new Material(materialData, materialData.attributes)
document.querySelector('#material-container').innerHTML += newMaterial.renderMaterialCard()
})
}
function patchMaterial(material, name, description, url, category_id) {
const patchJSON = {name, description, url, category_id}
fetch(`http://localhost:3000/api/v1/materials/${material.id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify(patchJSON),
})
.then(response => response.json())
.then(material => {
const materialData = material.data
let newMaterial = Material(materialData, materialData.attributes)
document.querySelector('#material-container').innerHTML += newMaterial.renderMaterialCard()
})
}
material.js
class Material {
constructor(material, materialAttributes) {
this.id = material.id
this.name = materialAttributes.name
this.description = materialAttributes.description
this.url = materialAttributes.url
this.category = materialAttributes.category
Material.all.push(this)
}
renderMaterialCard() {
return `
<div data-id=${this.id}>
<h3>${this.name}</h3>
<p>${this.description}</p>
<p><small><a href="${this.url}">${this.url}</a></small></p>
<p>${this.category.title}</p>
<button data-id=${this.id}>edit</button>
</div>
<br><br>`
}
static findById(id) {
return this.all.find(material => material.id == id)
}
renderPatchForm() {
return `
<form data-id=${this.id} >
<h2>Edit the Resource</h2>
<label>Name</label>
<input id='input-name' type="text" name="name" value="${this.name}" class="input-name">
<br><br>
<label>Description</label>
<textarea id='input-description' name="description" rows="8" cols="80" value="">${this.description}</textarea>
<br><br>
<label>URL</label>
<input id='input-url' type="text" name="url" value="${this.url}" class="input-text">
<br><br>
<label>Category</label>
<select id="categories" name="categories" value="${this.category.name}">
<option value="1">Criminal Justice Reform</option>
<option value="2">Bail Funds</option>
<option value="3">Clothing</option>
<option value="4">Organizations</option>
<option value="5">Mutual Aid</option>
<option value="6">Fundraisers</option>
<option value="7">Petitions</option>
<option value="8">Articles</option>
<option value="9">Artists</option>
<option value="10">Instagram</option>
</select>
<br><br>
<input id='edit-button' type="submit" name="submit" value="Edit Resource" class="submit">
</form> `
}
}
Material.all = []
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Beneficial Resources</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="src/material.js"></script>
<script type="text/javascript" src="src/index.js"></script>
</head>
<body>
<center>
<h1>A Space For Resources</h1>
<h5>An open space that hosts resources dedicated to urgent issues around the World.</h5>
</center>
<div class="form-container">
<form id="create-material-form">
<h2>Add a new Resource</h2>
<input id='input-name' type="text" name="name" value="" placeholder="Resource Name" class="input-text">
<br><br>
<textarea id='input-description' name="description" rows="8" cols="80" value="" placeholder="Enter the description of your Resource..."></textarea>
<br><br>
<input id="input-url" type="text" name="url" value="" placeholder="URL" class="input-text">
<br>
<h4>What Category is your Resource?</h4>
<select id="categories" name="categories">
<option value="1">Criminal Justice Reform</option>
<option value="2">Bail Funds</option>
<option value="3">Clothing</option>
<option value="4"& ...