Submit form data from client to Node.js (API)
Published: 2022-06-30 11:55:16

This is a fun one! 

It's common practice to have a form or input on a website where visitors can enter something in a search field and then expect some data back. 

So let's take a look at how we can do that!

Dependencies we'll use for this project:

- Express (a Node.js framework that provides broad features for building web and mobile applications)

- Nodemon (so our server automatically updates when we change the anything in our server file)

The first thing we're going to want to do is start a project with a basic index.html file. You can add this to the body of your HTML page 😎!

```html
  <h1>Welcome our test site! 👋🏾</h1>
 
  <form action="/find" method="POST">
    <input type="text" name="search-item" placeholder="Search here!">
    <button type="submit">Search</button>
  </form>
```

And here are some basic styles for your stylesheet:

```css
  h1{
    color: rgb(79, 75, 204);
    font-family: Arial, Helvetica, sans-serif;
  }

  h1, form{
    margin: 0 auto;
  }

  button{
    color: white;
    font-weight: bold;
    background-color: rgb(79, 75, 204);
    border-radius: 6px;
    padding: 4px;
  }
```

We'll go over the HTML portion in a few. Let's build our node server now!

First, in your terminal, run the following command:
`npm init`

Once you press enter, you'll be prompted to answer a few questions in the terminal, but you don't need to fill those out right now, you can always edit them later on directly in the file; just press enter until the questions go away.
This will initiate a package.json file in your project where your dependencies will live. 

The package.json file should look like this after you run the command.

``` json
{
  "name": "blogcode",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC"
}

```

Now we can add those dependencies mentioned in the beginning by running the following commands. 
` npm install express`
and
`npm install --save-dev nodemon
`

NOTE 📝: We're saving nodemon as a dev dependency because it's solely for our benefit when testing locally, it's not needed in production, so we add the `--save--dev` flag to tell our package.json that it's not needed past our testing phase.

Here's what our package.json file looks like now after adding the dependencies. 
![packagejson](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpf1pu93l1gjbzm0gvbt.png)
 

Now let's manually add one more line to the package.json file so when we're testing locally, we can use Nodemon to automatically update our server instead of manually needing to refresh it every time we make a change.
![packagejson2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvfbfk0jze8pnxqtjhtl.png)

We can create our server now! Go ahead and paste this code into your server file (I named mine server.js for convenience):

```javascript
const express = require("express")
const app = express()
const port = 3000

app.use(
  express.urlencoded({
    extended: true,
  })
)

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html")
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
```

In the first three lines, we are setting up our server variables. 
`const express = require("express")` : here we're importing the express package we installed earlier (`npm install express`)


`const app = express()` - creates our express app. 
`const port = 3000` - we'll use this variable to tell our app which port to listen to.

The following code is middleware, it parses incoming requests with urlencoded payloads and is based on body-parser. It pretty much allows us to read request objects 🤓, nothing crazy. 
```js
app.use(
  express.urlencoded({
    extended: true,
  })
)
```
Now for the good stuff 🔥

The `app.get()` is saying "Hey server, when we're on the root path/route, **send** our HTML page to be displayed."

And `app.listen()` is binding the app to the port on our machine, in this case it's listening to port 3000 which we defined as a variable at the top of the server file. 

Now in our terminal we can run that package.json script we added a few steps ago, go ahead and type`npm run dev` in your terminal, and you should see this: 
![start server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7s4uhygr90se2czkj0h5.png)

This means our server is running, and our app is listening for events that happen on that port!

Remember that form we added to the HTML page? We have 3 important pieces here for our server.

![formCode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/as1jtjo5arl5vhysje22.png)
 

1.) When the form is submitted, hit the `/find` route on our server (we haven't made this route yet, but it's coming).

2.) Make a POST request to the server, so we can do something with the data we're sending to this route.

3.) The key we'll use for our response object. 


Let's make the `/find` route in our server real quick. Add this to your server file:

```javascript
app.post("/find", async (req, res) => {
  const searchItem = await req.body.searchForThis
  console.log(searchItem)

  res.send(`We can search for this item on our backend:  ${searchItem}`)
})

```

Now that our server is running, we can type something into our HTML input field and submit (click search). We'll see our input logged to our server that's running in our terminal, and then our response to our website will be whatever is in the `res.send()`!

 Client side: 

![gif](https://media.giphy.com/media/GZ6aUc5NJ4bfziq7u2/giphy.gif)
 
Server: 
![server req](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk0zaicrt2rjjezbjb7k.png)
 
And there you have it! Passing data from the client side to your server is an every-day task; so it's nice to have an idea on how to do these things! 

Now that you have that data on your server side, you can make requests to APIs to upload and request data using that value we passed along!

If you have any questions or feedback, let me know, and we can share ideas! ✌🏾💙

Here's a puppy:
![puppy](https://images.unsplash.com/photo-1583511655826-05700d52f4d9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=688&q=80)

[doggy photo: Karsten Winegeart 🤘🏾](https://unsplash.com/@karsten116)

[cover photo: Claudio Schwarz 🙏🏽](https://unsplash.com/@purzlbaum)