0

I'm trying to create a very simple web app where users can create an event on a web calendar to be displayed. The calendar application I am using has the capability of reading a json file to get event information. I've gotten the calendar component working, and the api is set up to send data properly. Im having issues trying to process the data when it hits post portion of my api. I've narrowed it down particularly to my fs.writefile. I seem to be doing something wrong here. The rest of the code base works fine and when I comment out the section where I attempt to write the post data being sent to /createEvent The whole code works(minus the intended goal of writing to my json file)

Heres the error I get:

(node:12756) [DEP0018] DeprecationWarning: Unhandled promise rejections are `deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.`

Here is an example post of what my API is sending, but failing to process:

{ userInput: { title: 'Vinny', start: '2018-12-01', end: '2018-12-01' } }

Heres my code:

const express = require('express');
const routes = require('./routes/');
const app = express();
const port = 3000;
const router = express.Router();
const cors = require('cors');
const bodyParser = require('body-parser');
const helmet = require('helmet');
const fs = require('fs')
import ('./calendarevents.json');
routes(router);
app.use(cors()); // Allows for Cross origin requests
app.use(bodyParser.json()) // Turns all post requests to json
app.use(bodyParser.urlencoded({ extended: false }));
app.use(helmet()); // Helps secure apps with Http headers

app.use('/api',router); 

app.get('/', (req, res) => res.send('Hello World!'))

app.use(bodyParser.json())


app.get('/api/createEvent'), (req, res) => {
 res.render(req.body)
}

app.post('/api/createEvent', (req, res) => {
  console.log(req.body);
  //res.send("recieved your request!")

  const UserInput = JSON.stringify(req.body);
  fs.writeFile('./calendarevents.json', UserInput, (err) => {
  if (err) throw err; 
  console.log("The file was saved!");

  });

});

  app.listen(port, () => console.log(`StoreUI Backend listening on ${port}!`))
Vincent Morris
  • 640
  • 1
  • 9
  • 26

2 Answers2

1

You're throwing an error, but not handling it. You're also not sending a response to the post back to the client.

Rather than throwing an error, why not just send a 500 status?

app.post('/api/createEvent', (req, res, next) => {
    console.log(req.body);

    const UserInput = JSON.stringify(req.body);
    fs.writeFile('./calendarevents.json', UserInput, err => {
        if (err) {
            res.sendStatus(500);
        }
        else {
            console.log("The file was saved!");
            res.status(200).send("received your request!");
        }   
    });
});
Jim B.
  • 4,512
  • 3
  • 25
  • 53
0

You're not handling the error, so node is throwing a deprecation warning. Also, you're using import ('./calendarevents.json');, which is invalid syntax (unless your API is wrapped in webpack -- but, I'm also not sure why you're importing it in). And... your current setup will completely overwrite the JSON file each time a new event is sent. If you want to append it, see option 2.

The below is not very clean, but you can clean it up if you wrap fs calls in promises. For simplicity, I decided not to.

Option 1:

app.post('/api/createEvent', (req, res) => {
  const calanderEventPath = './calendarevents.json';
  const newEvent = JSON.stringify(req.body);

  try {
    const pathExists = fs.existsSync(calandEventPath); // check if path exists
    if (!pathExists) throw "The calandar JSON file has not been created yet.";

    let error;
    fs.writeFileSync(calanderEventPath, newEvent, 'utf-8' function(err) { // attempts to save newEvent to the calandar JSON path
      if (err) error = 'Unable to save the new event to the calandar JSON file.';
    });

    if (error) throw error;

    res.status(201).send("Successfully saved the event.");
  } catch (err) {
    res.status(500).send(err);
  }
});

Option 2:

app.post('/api/createEvent', async (req, res) => {
  const newEvent = JSON.stringify(req.body);   
  const calanderEventPath = './calendarevents.json';      
  let savedEvents;
  let error;

  try {
    const pathExists = fs.existsSync(calandEventPath); // check if path exists
    if (!pathExists) throw "The calandar JSON file has not been created yet."; 

    fs.readFileSync(calanderEventPath, 'utf8', function(err, currentEvents) { // attempt to read file to extract current event data
      if (err) error = "Unable to read the calandar JSON file.";

      savedEvents = JSON.stringify(currentEvents.push({ newEvent })); // push "newEvent" data into the current event data and set it to "savedEvents"
    }

    if (error) throw error;    

    fs.writeFileSync(calanderEventPath, savedEvents, 'utf8', function(err) { // attempts to save "savedEvents" to the calandar JSON path
      if (err) error = 'Unable to save the new event to the calandar JSON file.';
    });

    if (error) throw error; 

    res.status(201).send("Successfully added an event");
  } catch (err) {
    res.status(500).send(err)
}  
Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51