Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST data to NodeJS using fetch()

I've been trying to learn NodeJS following this NodeJs Youtube Tutorial.

I already worked with the Fetch API for a couple of months to get data from WordPress and Google Sheets back ends.

The last videos of the Youtube playlists are about creating a To Do List app with NodeJS and the npm's express, EJS and body-parser.

However, at part 4 of the To do list app, this "teacher" is using jQuery with Ajax to POST data to NodeJS (His jQuery Code Snippet). Since I've only been working with fetch() for AJAX POST requests, i wanted to continue with this method in plain JavaScript.

My ejs file, called todo.ejs, storing the HTML Template of the page looks like this:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="/assets/style.css">
    <!-- Works because of express middleware.
    Since we stored the public folder as a static folder,
    we can request anything within that folder from the url, such as
    127.0.0.1:3000/assets/styles.css
    -->

    <title>Todo List</title>
</head>

<body>
   <h1>My Todo List</h1>
    <div id="todo-table">
        <form>
            <input type="text" name="item" placeholder="Add new item..." required>
            <button type="submit">Add Item</button>
        </form>
        <ul>
            <% todos.forEach(todoList =>{ %>
             <li> <%= todoList.item %> </li>   
           <% }) %>
        </ul>
    </div>
</body>
<script src="/assets/script.js"></script>

</html>

My script.js (linked to the todo.ejs page) looks like this:

document.addEventListener("DOMContentLoaded", function (event) {
    let submitButton = document.querySelector("button");
    let textField = document.querySelector("input");

    submitButton.addEventListener("click", addItem);

    function addItem() {

        let newItem = textField.value;
        let todo = {
            item: newItem
        };

        fetch("/todo", {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(todo)
            }).then((res) => res.json())
            .then((data) => console.log(data))
            .catch((err) => console.log(err))
    }

});

And my controller handling all get/post requests, called todoController.js, looks like this:

let bodyParser = require("body-parser");
let urlencodedParser = bodyParser.urlencoded({ extended: false });

// Have some items already in place
let data = [{item: "Get milk"} , {item: "Walk dog"} , {item: "Clean kitchen"}];

module.exports = function (app) {

    //Handle get data requests
    app.get("/todo", function (req, res) {
        res.render("todo", {todos: data});
    });

    //Handle post data requests (add data)
    app.post("/todo", urlencodedParser, function (req, res) {
        console.log(req.body);
    });

    //Handle delete data requests
    app.delete("/todo", function (req, res) {

    });
};

Now, every time i populate the input field with some text and hit the enter button, my terminal outputs empty objects:

CMD output of POSTed data

Based on those empty objects, there has to be something wrong that my POST requests are not accepted/sent correctly.

My file tree looks like this: File tree of whole project

Anyone who maybe has (probably an obvious) answer to this? (I know I could just grab his jQuery Ajax code snippet to make it work, but I'm eagerly trying to understand it using plain Javascript)

Thanks in advance to everyone taking time to help me :)

like image 836
Tanckom Avatar asked Jun 14 '18 13:06

Tanckom


1 Answers

You need to use bodyParser.json instead of bodyParser.urlencoded.

As the names imply, urlencoded will parse url parameters while bodyParser.json will parse json in the body of the request.

like image 200
FINDarkside Avatar answered Sep 20 '22 10:09

FINDarkside