I am trying to edit a post and dynamicaly update the Dom with my editPost function
(The posts are created with another Javascript function).
function editPost(post_id){
// get the post text
const post_element = document.getElementById(post_id);
const post_text_element = post_element.querySelector('p.card-text');
const post_text = post_text_element.textContent.trim();
console.log(post_text_element)
// create the textarea and populate it with the content of the post
const textarea = document.createElement('textarea');
textarea.setAttribute('rows', 3);
textarea.setAttribute('cols', 50);
textarea.setAttribute('id', `edit-post-${post_id}`);
textarea.value = post_text;
// create the save button and add Event Listener
const save_button = document.createElement('button');
save_button.textContent = 'Save';
save_button.addEventListener('click', () => {
const new_post_text = textarea.value;
fetch('/update_post/' + post_id, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ new_text: new_post_text })
})
.then(response => response.json())
.then(data => {
const updated_post_text = data.new_text;
const updated_post_element = document.createElement('p');
updated_post_element.className = "card-text";
updated_post_element.textContent = updated_post_text;
post_element.replaceChild(updated_post_element, textarea);
post_element.removeChild(save_button);
});
});
post_element.replaceChild(textarea, post_text_element);
post_element.appendChild(save_button);
}
but when clicking the Edit button I get an error in the console pointing to the post_element.replaceChild at the bottom saying:
Uncaught DOMException: Failed to execute ‘replaceChild’ on ‘Node’: The
node to be replaced is not a child of this node.
at editPost (http://127.0.0.1:8000/static/network/index.js:214:18)
at HTMLButtonElement.onclick (http://127.0.0.1:8000/:75:9) editPost @ index.js:214 onclick @ (index):75
dont really get it…
Post_text_element is a html paragraph element
console.log(post_text_element) shows the right element.
below you can see the creation of the post_element
post_text_element is in the middle with class name "card-text"
// create a div element for each post
posts.forEach(post => {
let cardDiv = document.createElement('div');
cardDiv.className = "card";
cardDiv.setAttribute('id', post['id']);
cardDiv.innerHTML = `
<div class="card-body">
<div class="row card-title">
<span class="col">
<a id="user-link" href="profile/${post['user'][0].username}">
<h6>${post['user'][0].username}</h6>
</a>
</span>
<h7 class="col d-flex justify-content-end card-subtitle mb-2 text-muted">${post['timestamp']}</h7>
</div>
<p class="card-text">${post['text']}</p>
<div class="row">
<div class="col d-flex justify-content-start">
<button class="like-button" onclick="likePost(${post.id});">
♥
<span class="like-count">${post['total_likes']}</span>
</button>
</div>
${post['user'][0].id == request_user_id ?
`<span class="col d-flex justify-content-end">
<button class="edit-button" onclick="editPost(${post.id});">Edit</button>
</span>` : ''}
</div>
</div>
`;
2
Answers
For
Node.replaceChild(newChild, oldChild)
,Node
must be the immediate parent ofoldChild
. In your code,oldChild
ispost_text_element
but its parent is<div class="card-body">
, which is notpost_element
(post_element
is<div class="card" id=…>
). Instead of calling the.replaceChild()
method onpost_element
, get the parent ofpost_text_element
with.parentElement
and then call.replaceChild()
on that like:You may also need to do something similar within the
save_button.addEventListener()
callback too.So probably you’ll need the parent. I have tried to boil your code down to a minimal reproducable example. Maybe it helps.