Get the value from HTML by Express

In Express, there are three that we can get value from the HTML. That are req.params, req.body, and req.query. However, the values that we got have a little different meaning.

  1. req.params

the params is used to get the value from url. Here is a example as following:

edit.hbs

 <form action="/restaurants/{{restaurantContent._id}}?_method=PUT" method="POST">
      <div class="form-group mb-4 mt-6">
        <label for="name" class="form-label">中文店名 (Shop name in chinese)</label>
        <input
          type="text"
          class="form-control"
          id="name"
          name="name"
          maxlength="20"
          placeholder="請輸入中文店名..."
          value="{{restaurantContent.name}}"
          required
        />
      </div>
</form>

app.js (The router to get from edit.hbs)

app.put("/:id", (req, res) => {
  const restaurantId = req.params.id;
  return Restaurant.findById(restaurantId)
    .then((restaurantEditedInfo) => {
      for (const [key, value] of Object.entries(req.body)) {
        restaurantEditedInfo[key] = value;
      }
      return restaurantEditedInfo.save();
    })
    .then(() => res.redirect(`/restaurants/${restaurantId}`))
    .catch((error) => {
      console.log(error);
      res.render("error", { error: error.message });
    });
});

You can see it has form tag in edit.hbs and the action is a url which you want to show the specific data id. So the url will be"http://locakhost:3000/restaurants/XXX_id?_method=PUT”. When you use the req.params, it will show the id string in it object.(The id can be a number) And you can see the app.js get it by the req.params.id

  1. req.body

In general, it used in POST and PUT method when you want to build the form in the web like the restaurant list or some sensitive data. The example is as following (app.js is the same as above)

edit.hbs

      <div class="form-group mt-4">
        <label for="phone" class="form-label">聯絡電話 (Shop phone number)</label>
        <input
          {{! !!注意電話的部分會不會變成number,資料格式是屬於字串 }}
          type="tel"
          class="form-control"
          id="phone"
          name="phone"
          placeholder="請輸入電話號碼 (please type your phone)"
          value="{{restaurantContent.phone}}"
          required
        />
      </div>

      <div class="form-group mt-4">
        <label for="category" class="form-label">料理類別(Food style)</label>
        <input
          list="category-options"
          class="form-control"
          id="category"
          name="category"
          placeholder="如無需要的選項,請自行填寫 (If you don't find out the option, please type yourself.)"
          value="{{restaurantContent.category}}"
          required
        />
        <datalist id="category-options">
          <option>義式料理 (Italy)</option>
          <option>法式料理 (French)</option>
          <option>日本料理 (Japan)</option>
          <option>中東料理 (Middle East)</option>
          <option>中式料理 (Chinese)</option>
          <option>歐式料理 (European)</option>
          <option>酒吧 (Bar)</option>
          <option>咖啡廳 (Cafe)</option>
        </datalist>
      </div>

When the client side submit the form with content, it will be stored in the req.body and it is a JSON data. You have to pass the body-parse otherwise you will get an error

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

The input or button tag need to give their name to catch the value. Fro example, req.body in this example will be as following.

req.body = {
   phone: XXX, // number
   category: 'XXXX' // string
}
  1. req.query

It is usually used for searching, sorting, filtering , pagination, e.t.c. When client side send the keyword to searching something, the url will show the value and use the req.query to catch it.

index.hbs

 <form action="/sort" method="GET">
    <div class="input-group ms-2" style="width: 200px; height:40px;">
       <select class="form-select text-center" name="sort" onchange="">
          <option value="a-z" {{#if sort.a-z}}selected{{/if}}>A->Z</option>
          <option value="z-a" {{#if sort.z-a}}selected{{/if}}>Z->A</option>
          <option value="category" {{#if sort.category}}selected{{/if}}>類別</option>
          <option value="location" {{#if sort.location}}selected{{/if}}>地址</option>
        </select>
        <button type="submit" class="btn btn-major">排序</button>
     </div>
  </form>

app,js

app.get("/sort", (req, res) = > {    
    const reqValue = req.query
    const sortValue = reqValue.sort;
    const sortOption = {
      "a-z": { name: "asc" },
      "z-a": { name: "desc" },
      category: { category: "asc" },
      location: { location: "asc" },
    };

    const sort = sortValue ? { [sortValue]: true } : { "a-z": true };

    Restaurant.find()
      .lean()
      .sort(sortOption[sortValue])
      .then((restaurantList) => res.render("index", { restaurantList, sort }))
      .catch((error) => {
        console.log(error);
        res.render("error", { error });
      });
})

For example, the url will be localhost:3000/?sort=a-z (or z-a, location, category.)


Conclusion:

So, when we make the web with form and want to get these value, we have to know which method you have to use to catch it. req.query, req.body or req.params all of them have different meaning.

(if this article have the wrong place, please comment to me)

Ref:

https://medium.com/ling-ni-lee/express-js-%E5%8F%96%E5%BE%97%E7%B6%B2%E9%A0%81%E5%8F%83%E6%95%B8%E7%9A%84%E4%B8%89%E7%A8%AE%E6%96%B9%E6%B3%95-39725d8f3211