How perform PATCH request from html form using NodeJS? - javascript

This was my attempt to perform a patch request on an HTML form from the frontend to MongoDB database via NodeJS API.
This is a Nodejs API structure
app.route("/requests/:rollno")
.get(function(req, res) {
// get method to find a query
})
.patch(function(req, res) {
Request.update({
rollno: req.params.rollno
}, {
$set:req.body
},
function(err) {
if (!err) {
res.send("Successfully updated requests");
}else{
res.send(err);
}
}
);
});
On the frontend side of the form
<%- include('partials/header') %>
<h1>Recent requests</h1>
<% for(let i = 0; i < posts.length; i++) { %>
<article>
<form action="/requests/21" method="PATCH">
<input type="text" name="status[0]">
<div id="participant"></div>
<br>
<button type="button" onclick="addParticipant()">Add</button>
<button type="button" onclick="delParticipant()">Remove</button>
<div class="btn-block">
<button type="submit" href="/success">Submit Request</button>
</div>
</form>
</article>
<% } %>
The form is not actually updating the information on the actual server. But with the postman, the data is getting updated.What's the best resolution for the same or is there any alternate method for the same ?

<form action="/requests/B194057EP" method="PATCH">
This is invalid, HTML forms method attribute only supports GET and POST method. <form method="put"> is invalid HTML and will be treated like a GET request.
Now to solve this, you can make use of Jquery AJAX to send data from the client-side to your backend.
$.ajax({
url: '<api url>',
type: 'PATCH',
data: {
data: sendData
},
success: function () {
}
})
;

In vanilla JS, you can use promises, as well as async/await to do so, this is a basic example of it.
async patching() {
const responseFlow = await fetch(URL, {
method: "PATCH",
headers: {
'Content-Type': 'application/json'
},
// The content to update
body: JSON.stringify({
name: "New name"
})
})
}

Related

Response is coming as */* instead of turbo_stream in rails 7

when hitting the stimulus controller it's going to the rails stimulus controller but the request is coming as */* but I want this request as turbo_stream, so how can i do that.
app/views/stimulus/index.html.erb
<div data-controller="toggle" data-toggle-url-value="<%= root_path %>">
<div>
<p class="mt-5">Copy text content</p>
<input type="text" data-toggle-target="txt"/>
<button data-action="click->toggle#copy">Copy</button>
</div>
app/controllers/stimulus_controller.rb
def index
end
app/javascript/controllers/stimulus_controller.js
static targets = ["txt"]
static values = { url: String }
connect() {
this.hideBtnTarget.hidden = true
console.log(this.urlValue);
fetch(this.urlValue).then((success) => {
console.log(success);
}).catch((e) => {
console.log(e);
})
}
copy(){
let txt = this.txtTarget
txt.select()
document.execCommand("copy")
txt.value = ""
}
I want a response as turbo_stream instead of */* .
thanks!
To get request as turbo_stream you need to add code inside fetch method headers.
fetch("your url path", {
method: "get",
headers: {
Accept: "text/vnd.turbo-stream.html"
},
});

How do I do this with javascript fetch

I was checking out this answer.
It's basically a request to Mailchimp to send a confirmation email to the user when they submit their email.
The code works perfectly with jquery. But I don't like jquery. And it's kind of annoying to have to add it just for this tiny snippet, since I won't be using it in the rest of my project. I already tried "translating" this into vanilla javascript using fetch but it doesn't seem to work.
function register($form) {
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serialize(),
cache : false,
dataType : 'json',
contentType: "application/json; charset=utf-8",
error : function(err) { alert("Could not connect to the registration server. Please try again later."); },
success : function(data) {
if (data.result != "success") {
// Something went wrong, do something to notify the user. maybe alert(data.msg);
} else {
// It worked, carry on...
}
}
});
}
EDIT
Some suggested I should add the HTML form:
I am doing all this because I want to send the user email to my MailChimp subscription list. But I want it to do it directly from my website without redirecting to the Mailchimp subscription page.
<form action="https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=?" method="get" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate newsletter__form" target="_blank">
<label for="mce-EMAIL">Ingresa tu correo electrónico:</label>
<input type="email" placeholder="ejemplo#gmail.com" value="" name="EMAIL" class="required textfield email__textfield" id="mce-EMAIL">
<input type="submit" value="suscribirme" name="subscribe" id="mc-embedded-subscribe" class="button raise">
<div id="mce-responses" class="clear">
<div class="response" id="mce-error-response" style="display:none"></div>
<div class="response" id="mce-success-response" style="display:none"></div>
</div> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_070e69e5e3e6e664a8066e48f_0bf75ac6c4" tabindex="-1" value=""></div>
</form>
I also found out jquery ajax method get accepts the data argument but it takes what's inside of the data and adds it to the URL. So it's still a get request with no body. I am trying to find a way to do that but with fetch but somehow the jquery URL has things I don't know where they come from. I also tried doing this with POST method and fetch but apparently, the server doesn't allow that.
For what is worth this is how the URL generated by jquery request looks like:
https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=jQuery35105022544193369527_1633147928440&EMAIL=email123456%40gmail.com&b_070e69e5e3e6e664a8066e48f_0bf75ac6c4=&_=1633147928441
And this is how I can trick my URL to look like with fetch. Here I get a CORS error
https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=?&EMAIL=paula.uzcategui68%40gmail.com&b_070e69e5e3e6e664a8066e48f_0bf75ac6c4=
And this is what I'm doing with fetch
function register(form) {
data = new FormData(form);
data = Object.fromEntries(data);
data = Object.entries(data);
let arroba = /#/gi;
let action = form.getAttribute("action")+ "&"+ data[0][0] +"="+ data[0][1].replace(arroba, '%40') + "&" + data[1][0] + "=" + data[1][1]
// console.log(action)
fetch(action, {
method: 'get',
cache: 'no-cache',
headers: {
'content-type': 'application/json; charset=utf-8'
},
})
.then(response => response.json())
.catch(error => {
alert("Could not connect to the registration server. Please try again later."+ error)
});
}
Try this, it is the exact solution for your question (I hope). If you still get stuck please comment down, I will explain.
async function register(form) {
let data = new FormData(form);
data = JSON.stringify(Object.fromEntries(data)); // convert formdata to json
let response = await fetch(form.action, {
method: form.method,
body: data,
cache: 'no-cache',
headers: {
'content-type': 'application/json; charset=utf-8'
}
})
.then(response => response.json())
.catch(error => {
alert("Could not connect to the registration server. Please try again later.")
});
}

Form submit value giving null - mongoose and express js

I am trying to make a way to send data from a basic html form to mongodb using express. but it's giving me null when I post it.
I used the following Schema : commentname: String.
Here's the HTML:
<form id="form" onsubmit="return false;">
<input type="textbox" id="cmt-1" placeholder="comment here"/>
</form>
<button type="button" onclick="submit()" class="submit">
submit
</button>
JS:
var cmt = document.getElementById('cmt-1').value;
var comment = {commentname: ''};
comment = {commentname: cmt};
function submit () {
async function postData (url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'same-origin',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData(
'https://realtime-comt-system-100.glitch.me/comments/add',{comment}
)
.then(data => { console.log(data); });
}
What am I missing?
just try this code but check the url i put . don't put the whole url just put the path name .
also take this code copy and paste , the html and the java script take them both because i changed both of them
var form = document.getElementById('form');
form.addEventListener('submit', async(e) => {
e.preventDefault();
let cmt = form.cmt.value;
let data = {commentname: cmt};
const response = await fetch('/comments/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(res =>{
console.log(res)
}).catch(err){
console.error(err)
}
})
<form id="form">
<input type="textbox" id="cmt-1" name='cmt' placeholder="comment here"/>
</form>
<button type="submit" onclick="submit()" class="submit">
submit
</button>
The problem is not being caused by the code posted above.
It's a Mongoose problem. You are trying to create two documents with the same id, when that id has been specified unique to Mongoose.
This is what the code is posting in the body to the backend, a JSON string:
{"comment":{"commentname":"my sample comment"}}
The fact that you're posting an object inside an object looks suspicious. This pattern would be more common:
{"commentname":"my sample comment"}
But since there is no backend code posted, it's impossible to tell if this is correct.
When I tried posting {"comment":{"commentname":"my sample comment"}} to the backend URL using Postman, I received the following response code:
400 Bad Request
The response body:
"Error: MongoError: E11000 duplicate key error collection: database.comments index: commentname_1 dup key: { commentname: null }"
From Mastering JS - Debug E11000 Errors in Mongoose
MongoDB's E11000 error is a common source of confusion. This error occurs when two documents have the same value for a field that's defined as unique in your Mongoose schema.
Mongoose models have an _id field that's always unique.

Improperly sending form data in html

So i would like to send Whatever i type in my input bar in to be sent to whatever api link via post method. But whenever i send it i get {} . The problem is when i dont send anything in the input bar A.K.A left blank and press submit i still get {}. But when i type gibberish its still {} . So i assume whatever i typed in is not being sent to the api link.
Also when i hard code something like body: JSON.stringify(this.myForm) it shows up as a response in the back end. So i believe i error lies withing this body of my fetch request. heres my code what should i put for the body.
<html>
<body>
<h1>Draft V0.1</h1>
<form class="form" id="myForm">
<label for="skill">add skill</label>
<input type="text" name="skill" id="skill">
<button type="submit">Submit</button>
</form>
<script>
const myForm = document.getElementById('myForm')
myForm.addEventListener('submit', function (e) {
e.preventDefault();
const formData = new FormData(this);
fetch('https://fj5s3i60a8.execute-api.us-east-1.amazonaws.com/updateSkill', {
method: 'post',
body: JSON.stringify(new FormData(myForm)),
headers:
{
"Content-Type": "application/json; charset=utf-8",
"Accept": 'application/json'
}
}).then(function (response) {
console.log(response)
return response.json();
});
});
</script>
</body>
</html>
Note I was blindly playing around with the body to see what i can parse through it but i would end up getting cors errors.
Thank you in advance
const thisForm = document.getElementById('myForm');
thisForm.addEventListener('submit', async function (e) {
e.preventDefault();
const formData = new FormData(thisForm).entries()
const response = await fetch('https://reqres.in/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(Object.fromEntries(formData))
});
const result = await response.json();
console.log(result)
});
<html>
<body>
<h1>Draft V0.1</h1>
<form class="form" id="myForm">
<label for="skill">add skill</label>
<input type="text" name="skill" id="skill">
<button type="submit">Submit</button>
</form>
</body>
</html>

Multiple Submit Buttons - html express node js

I'm trying to do a like/dislike system. So essentially, there are two buttons on the html side.
<form method="post" name="ratings">
<input type="submit" name="vote" value="like">
<input type="submit" name="vote" value="dislike">
</form>
However, I only know how to do a single function. How can I seperate it? I'm working in node js.
So, like the first line of code looks like this:
router.post('/test/*', function (req, res) {
Like what would the if statement look like in javascript? or do I have to change the html code and do something with onclick? Any response would be appreciated.
I figured it out. You can get the name from req.body.vote and then use that value to do whatever.
var inputValue = req.body.vote;
if (inputValue == "like") {
...
I suggest you to use ajax, somelike this..
Buttons:
<button name="btnLike" value="like" onclick="like()">
<button name="btnDislike" value="dislike" onclick="dislike()">
JS:
function like(){
$.ajax({
url: "http://localhost:3000/like",
type: "POST",
data: {like: 'yes'}, //send this to server
success: function(returned) {
console.log(returnet); // here can get the return of route
},
error: function() {
}
});
}
function dislike(){
$.ajax({
url: "http://localhost:3000/dislike",
type: "POST",
data: {dislike: 'yes'}, //send this to server
success: function(returned) {
console.log(returnet); // here can get the return of route
},
error: function() {
}
});
}
Routes:
router.post('/like', function (req, res) {
}
router.post('/dislike', function (req, res) {
}
You can also use formaction
<button type="submit" formaction="/like" name="vote"></button>
<button type="submit" formaction="/dislike" name="vote"></button>
Below is the link
Parsing Form With Multiple Submits

Categories

Resources