Postgres does not save changes on refresh - node.js

I'm still in the process of learning, I'm attempting to build a fullstack app and I'm facing a little issue.
Even after making changes to the database after the request, refreshing the page on the frontend doesn't preserve the changes.
This is how I'm handling my post requests
app.post('/api/data', (req, res) => {
handlePost(req.body.index, req.body.formulaString) // runs asynchronously, and runs the query for making the changes
.then(() => {
client.query('SELECT * FROM table ORDER BY id ASC')
.then((x) => {
res.send(x.rows)//the response works exactly as intended, the frontend gives the correct values etc.
})
})
})
Although if I just restart the server, all the changes are saved and preserved even after I refresh the frontend.

I would add a .catch((error) => { console.log(error) }); to your promise handling and see if it doesn't clue you in.

Related

Mongoose document.save() method is blocking websocket execution

I have a NodeJS app running a websocket server using the ws npm package. In a callback from the message event ws.on("message", async (rawData, isBinary) => {}), I'm trying to update a document and then save it. The .find() method works fine, but the .save() method blocks execution completely.
const users = await Promise.all(
game.players.map((p) => User.findById(p.id)) // This works fine
);
// mess with users here
await Promise.all(users.map(u => u.save())) // <-- This doesn't work
await users[0].save() // <--- This doesn't work either
users[0].save((err, doc) => {
// This doesn't work either
})
users[0].save().then(doc => {
// console.log(doc) // <-- This doesn't work either
})
For starters, is this even possible ? Or am I thinking about it the wrong way and should I trigger some kind of POST request from the client to hit my http server instead to do the mongodb operations ? In any case, I'm struggling to understand why this is not possible.
Also something interesting is when I tried logging everything everywhere I tried to do the following
console.log(users[0].save())
users[0].save((err, doc) => {
if (err) console.log(err) // <-- no log here
console.log(doc) // <-- no log here
})
which threw mongoose's ParallelSaveError: Can't save() the same doc multiple times in parallel. So I'm guessing the action does take place but not entirely ?
Any insight on this is welcome.

Update Frontend after using Delete Route in Express.js

I have created a delete route in express.js that looks like the following:
router.delete("/notes/:id", (req, res) => {
console.log("delete route called")
const noteToRemove = findById(req.params.id, notes);
const result = notes.filter(note => note !== noteToRemove)
console.log(result);
fs.writeFileSync(
path.join(__dirname, '../../db/db.json'),
JSON.stringify({ notes: result }, null, 2)
);
)}
findById is a function I have declared in another file to locate an item in my database db/db.json that locates an item based on an ID I created earlier.
The issue here is that this code will remove an item from the database, but I want the frontend to show the updated list from the database. How does one reload the frontend to see the updated changes in the database?
Two things:
You will need to include a response in your server side method to let the client know that the resource was deleted. You should also add responses with error codes in cases something goes wrong, but for simplicity here we only address the nominal case.
router.delete("/notes/:id", (req, res) => {
console.log("delete route called")
const noteToRemove = findById(req.params.id, notes);
const result = notes.filter(note => note !== noteToRemove)
console.log(result);
fs.writeFileSync(
path.join(__dirname, '../../db/db.json'),
JSON.stringify({ notes: result }, null, 2)
);
res.end(); // respond to the client to let them know we are finished
)}
On the front-end you will need to react to this response and reload the resources. This highly depends on how your front end is structured and how it gets data from the server. As a hack, for now, you can just call location.reload(), which will do the trick in the vast majority of cases -- but isn't very elegant of course nowadays where you could refetch and render just parts of the data and page.

First time fetching API call is really slow - Node JS, React, Express

I have a website that is making a GET call to my backend database. The first time the website calls the API it takes 11 seconds, clearly, this is too long. But if I refresh the page and give it another go, it is super fast in less than a second.
I tried to find some solutions, so I opened DevTools and found this:
For some reason, the TTFB (Time to First Byte) takes 10 seconds!
How can I reduce the TTFB the first time the website calls the Rest API?
Here is my React code which is using Axios to fetch the rest API:
axios
.get(
"https://MY.API",
{
headers,
}
)
.then((response) => {
this.setState({
response: response.data,
});
})
.catch((err) => {
console.error(err);
});
Here is my backend code using Express, Mongoose, and MongoDB
router.get("/", async (req, res) => {
try {
const response = await Model.find();
res.json(response);
} catch (err) {
res.json({ message: err });
}
});
I would say that this is a pretty standard piece of code. I don't know why the TTFB is so much.
What tips I can implement to reduce the original wait time? This is annoying to my users.
Thanks!

Node JS GET API's not working with new data

I am using Node JS and MYSQL. When I add new data to my project, it writes to the database. Then when I want to GET this data with another API, it doesn't come. When I try again after about a minute, it comes on. However, right after I send a request via Swagger, data comes from the outside (Postman or Panel) on my request again.
My simple Controller.
exports.GetAll = (req, res, next) => {
ThisModel.GetAllSQL()
.then((response) => {
res.status(200).json(response[0]);
}).catch((error) => {
res.status(400).send();
console.log('Senaryo listesi çekilirken bir hata meydana geldi: ' + error);
})
}
.then((response) => {
res.status(200).json(response[0]);
})
Judging from the line above, it looks like you're getting a list/array of data, but only returning the first item in the list response[0].
Maybe this is what you're looking for:
.then((response) => {
res.status(200).json(response);
})

Expressjs Firebase React Redux Cannot set headers after they are sent to the client

I've been researching this issue for several hours now and found something odd. Using ExpressJS, Firebase, and React for a small app, and need to call the Firebase Database via the Express Backend, and I also need to make post requests to store data in the database via the Express Backend.
Functionality: I make a post request to the backend to add data to the database. Since Firebase is real time db, the data will immediately reflect on the page.
Problem: The issue is, when I make a post call to the backend and that completes, the page refreshes but the data doesn't show because of this
ERROR: [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
/**
* Add new note to Firebase
* Real-Time Database
*/
app.post('/addNote', (req, res)=> {
var title = req.body.note.title;
var body = req.body.note.body;
var userId= req.body.note.uid;
db.notes.push({
title: title,
body: body,
uid: userId
})
res.send("Success")
})
app.get('/all', (req, res, next)=> {
db.notes.on('value', snapshot => {
return res.send(snapshot.val());
})
})
Possible Solution: I've found that using the code below, I can make a post request, manually refresh the page, and the data will reflect with no header error. I'm trying to code the proper functionality but can't seem to figure out where the code is sending multiple responses with the db.notes.on because I'm only sending res.send one time. The clear difference is (.on listens and updates immediately, while .once requires manual refresh)
/**
* Add new note to Firebase
* Real-Time Database
*/
app.post('/addNote', (req, res)=> {
var title = req.body.note.title;
var body = req.body.note.body;
var userId= req.body.note.uid;
db.notes.push({
title: title,
body: body,
uid: userId
})
res.send("Success")
})
app.get('/all', (req, res, next)=> {
db.notes.once('value', snapshot => {
return res.send(snapshot.val());
})
})
An on("value" listener to Firebase will fire:
straight away with the current value of the data,
and will then later also fire when the data changes.
Since you're sending the data in the response to the client in #1, the response will be closed/finished by the time #2 happens.
By using a once("value" listener this problem doesn't happen, since once() removes the listener after #1.

Resources