Front end JS fetch(POST) request being sent as a GET? - javascript

So this fetch request is called on the submit button.
For some reason, in the dev tools, it goes through as a GET. Tested the request in Insomnia, and it ends up returning the site to me (the handlebars site)... and none of my console logs ever show up (on the backend or the front)
Front End
const newPostSubmit= async function(event) {
console.log('didnt make it');
event.preventDefault()
console.log('made it');
const title = document.getElementById('post-title').value;
const content = document.getElementById('content').value;
const response = await fetch(`/api/posts/`, {
method: 'POST',
body: JSON.stringify({
title,
content
}),
headers: {
'Content-Type': 'application/json'
}
});
if (response.ok) {
console.log('Post Success!')
// document.location.replace('/dashboard');
} else {
alert(response.statusText);
}
}
document.getElementById('submit-post').addEventListener('submit', newPostSubmit);
Back End Route To Be Used
router.post('/', checkAuth, (req, res) => {
const body = req.body
console.log(body);
Post.create({ ...body, userId: req.session.userId })
.then(dbPostData => {
console.log(dbPostData);
res.json(dbPostData)
})
.catch(err => {
console.log(err);
res.status(500).json(err);
});
});

The problem was with my HTML. The id of 'submit-post' was placed on the button, but needed to be on the form itself (the button was within the element) which is why the function would never run

Related

How to code a checkbox that saves changes after refreshing page

I'm trying to change the checkbox data on the server using the patch method, but I can't do it. Give me an advise, please, how to do it correctly.
I send a patch request, 202 code is returned. In the preview (developer tools in the browser) it is shown that the changed data is returned from the server, but for some reason the changes do not occur in the db.json file. After I check the checkbox and refresh the page it’s like I never checked the box.
I need an input checkbox that will send a PATCH request to the server to change the TODO-list state.
What I have so far:
async function editCheckbox(id) {
try {
checkbox = {
completed: document.querySelector(`[data-id="${id}"]` + ' input[type="checkbox"]').checked
}
await fetch('http://localhost:8080/todo/' + id, {
method: 'PATCH',
body: JSON.stringify(checkbox),
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
});
} catch (err) {
console.log(err);
}
}
And I use a patch on the route:
app.patch("/todo/:id", (req, res) => {
const { id } = req.params;
let rawdata = fs.readFileSync("db.json", "utf8");
let content = JSON.parse(rawdata);
if (!content.find((i) => i.id == id)) {
return res.status(404).json({ message: "Todo with that id not found" });
} else {
const newTodo = req.body;
const toWrite = content.map((i) => {
if (i.id === id) {
return newTodo;
}
return i;
});
fs.writeFileSync("db.json", JSON.stringify(toWrite), (err) => {
if (err) {
console.error(err);
}
});
res.status(202).json(newTodo);
}
});

how to pass URL further in to response using fetch?

I have this fetch request a I am accepting it to
send me a statement !! if certain conditions are met
redirect me to anther page after certain time
problem is those 2 don't seem to work together if I send json resp the link is pointing to the default one future more I cannot pass the URL further down the response.
// Server side
exports.redirect = async (req, res, next) => {
//res.status(403)
res.json({ Error: 'Plase try again' })
res.redirect('/signup')
}
// Client side
fetch('/redirect', {
credentials: "same-origin",
mode: "same-origin",
method: 'POST',
//redirect: 'follow',
headers: {
"Authorization": `Bearer ${jwt}`,
"Content-Type": "application/json"
},
body: JSON.stringify(inputJSON)
})
.then(resp => {
console.log(resp.url)
return Promise.all([resp.json()])
}
).then(data => {
console.log(data);
let jsonData = data[0]
let div = document.querySelector(".form-group");
div.insertAdjacentHTML('afterend', `<div id="response">${jsonData.Error}</div>`)
//setTimeout(windows.location = data.url, 5000);
})
.catch((error) => {
console.error(error);
}).catch(err => {
if (err === "server") return
console.log(err)
})
}
})
For the general situation of when you want to pass something from an upper .then to a lower one, you'd be almost there, you just need to add the resp.url to the Promise.all array you already have:
.then(resp => {
return Promise.all([resp.json(), resp.url])
}
).then(([data, url]) => {
const div = document.querySelector(".form-group");
div.insertAdjacentHTML('afterend', `<div id="response">${data.Error}</div>`);
setTimeout(() => window.location = url, 5000);
})
But it doesn't make much sense to have a response that both has .json() and a redirect - pick one or the other. I'd recommend only a .json:
exports.redirect = async (req, res, next) => {
res.json({ Error: 'Plase try again', url: '/signup' });
}
.then(res => res.json())
.then(result => {
div.insertAdjacentHTML('afterend', `<div id="response">${result.Error}</div>`);
setTimeout(() => window.location = result.url, 5000);
})
Also make sure to pass a callback to setTimeout, and to use window.location, not windows.location.
Your final .catch(err => { block is superfluous too, it'll never be entered into and doesn't really make any sense anyway - feel free to completely remove it.

SyntaxError: Unexpected end of input in fetch API

I face a new problem that has been asked before in this link. But It is not relevant to my problem.
What I have implemented is a very simple API using nodejs, express-framework and mongoose.
The problem is with fetch API. I want to submit some ID and post it to the server. In the server side I redirect it to the proper URL base on the ID that user entered. Whenever I test this part, this error is being raised in front-end side and points to return response.json() line.
SyntaxError: Unexpected end of input
Here is my code:
Front-End:
function submitCode(){
var nationalCode = document.getElementById('nationalCode').value
var data = {
nationalCode: nationalCode,
creationDate: new Date().toLocaleDateString()
}
fetch('/submit', {
method: 'POST',
redirect:'manual',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(data)
},
).then(response => {
return response.json()
}).then(jsonData => {
console.log('success:', jsonData)
history.pushState(null, null, "/lashkhor")
}).catch(e => {
console.log('error:', e)
return e
})
}
Back-End:
app.post('/submit', (req, res) => {
var nationalCode = req.body.nationalCode
var creationDate = req.body.creationDate
query = {'nationalCode': nationalCode}
nationalCodeModel.find(query, (err, success) => {
if (err) {
console.log('error:', err)
}
else if (success.length == 0){
nationalCodeModel.create({
nationalCode: nationalCode,
creationDate: creationDate
})
console.log('salam khoshgele daei!')
res.redirect('/khoshgeledaei')
}
else if (success.length > 0) {
console.log('lashkhor detected')
res.redirect('/lashkhor')
}
})
})
app.get('/lashkhor', (req, res) => {
console.log('here')
res.send('salam')
})
I can't find any hint to solve it. I would be thankful if anyone could help me.
PS: Whole code is available in this repository
Thanks!
You are trying to parse text into json.
You can use res.json() instead of res.send() from your backend.

Fetch API response with react and Express.js won't show any result with console.log

I have a login form that sends data to an Express.js backend using fetch. On the client side, when I want to display the results of the fetch call when it completes nothing is displayed (and it never reaches the data callback). I don't seem to be getting any errors, but I know that the data is successfully being sent to the backend.
Here's the Express.js server code:
const express = require('express');
const User = express.Router();
const bcrypt = require('bcrypt');
const user = require('../Models/user');
this is edited
function loginRouteHandler(req, res) {
user.findOne(
{
where: {
userName: req.body.userName,
},
},
)
.then((data) => {
if (bcrypt.compareSync(req.body.password, data.password)) {
req.session.userName = req.body.userName;
req.session.password = req.body.password;
console.log(req.session);
res.status(200).send('Success!');
} else {
res.status(400).send('some text');
}
});
}
User.route('/').get(getRouteHandler);
User.route('/register').post(postRouteHandler);
User.route('/login').post(loginRouteHandler);
module.exports = User;
And here's the fetch call:
fetch('http://localhost:4000/login',{
method: 'POST',
headers: {
'Accept': 'application/json,text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({
userName: this.state.userName,
password: this.state.password,
}),
}).then((response)=>{
if(response.ok){
console.log(response)
}
else {
console.log("a problem")
}
}).then((data)=>{
console.log(data)
});
In your loginRouteHandler, if the bcrypt compare succeeds nothing is returned in the response. So in the first branch of the if statement, put res.send('Success!') or something similar.
Here's an example:
function loginRouteHandler(req, res) {
user.findOne(
{
where: {
userName: req.body.userName,
},
},
)
.then((data) => {
if (bcrypt.compareSync(req.body.password, data.password)) {
req.session.userName = req.body.userName;
req.session.password = req.body.password;
console.log(req.session);
res.status(200).send('Success!');
} else {
res.status(400).send('some text');
}
});
}
UPDATE: you're also not getting the output of the fetch response with .text() or .json(). You have to update the fetch call to the following:
fetch(/* stuff */).then((response)=>{
if(response.ok){
console.log(response)
}
else {
console.log("a problem")
}
return response.text()
}).then((data)=>{
console.log(data)
});
Remove ok from response.ok
Remove .then((data)=>{ console.log(data) });
And check console log.
}).then((response)=>{
if(response){
console.log(response)
}
else {
console.log("a problem")
}
}).then((data)=>{
console.log(data)
});

Server is restarted after an axios request with express

My problem is, My project's server is restarted After an axios request with express.
I can see http://localhost:3000/__webpack_hmr 200 OK in console of chrome.
when I add vocabulary to data or remove that, server is restarted.
This is the vue client code. (github link to file)
methods: {
addVocabulary () {
var vm = this
this.$validator.validateAll().then((result) => {
if (result) {
axios.post('/api/vc/add', {
vocabulary: this.vocabulary
}).then(function (response) {
vm.vocabularies = response.data
}).catch(function (error) {
console.log(error)
})
this.vocabulary = ''
} else {
console.log('Not valid')
}
})
},
remove (id) {
var vm = this
axios({
method: 'delete',
url: '/api/vc/remove',
data: {id: id},
headers: {'Content-Type': 'application/json'}
}).then(function (response) {
vm.vocabularies = response.data
}).catch(function (error) {
console.log(error)
})
}
}
And this is the server side code.link to file
router.post('/vc/add', function (req, res, next) {
if (!req.body) return res.sendStatus(400)
let vocabulary = req.body.vocabulary
let objVocabulary = {}
objVocabulary.id = 10
objVocabulary.content = vocabulary
vocabularies.push(objVocabulary)
fse.outputJson(file, vocabularies, err=>{
console.log(err);
fse.readJson(file, (err, data) =>{
res.json(data);
})
})
})
/* DELETE remove voca */
router.delete('/vc/remove', (req, res, next) =>{
if (!req.body) return res.sendStatus(400)
let id = req.body.id
var index = vocabularies.findIndex(voca => voca.id === id);
vocabularies.splice(index,1);
fse.outputJson(file, vocabularies, err=>{
console.log(err);
fse.readJson(file, (err, data) =>{
res.json(data);
})
})
})
Here's my project link to github,
I don't know why..
I see that you are using backpack.
Their documentation quotes: Live reload (on saves, add/delete file, etc.)
So, if you the JSON file you are manipulating in your server code is in a folder watched by backpack, hot module reload will kick in and restart the server.
Solution: Move the json to some other directory --> your database shouldn't be part of your source code anyways.

Categories

Resources