21-Nodejs Course 2023: Advanced Request Data Handling
Tags: node, typescript, mongodb, fastify
Published: 2022-11-01 08:28:40

---
title: 21-Nodejs Course 2023: Advanced Request Data Handling
published: true
description: 
series: Nodejs Course 2023
tags: nodejs, typescript, mongodb, fastify
#cover_image: 
# Use a ratio of 100:42 for best results.
---

We've successfully created our own Request class, now let's add some methods to allow us getting data from the request.

## Request Input

Our first method we'll use here is `input` which will grab us a value from the request body, query string, or URL parameters.

```ts
// src/core/http/request.ts

  /**
   * Get the value of the given key from the request body, query or params
   */
  public input(key: string, defaultValue?: any) {
    return (
      this.request.params[key] ||
      this.request.body[key]?.value ||
      this.request.query[key] ||
      defaultValue
    );
  }
```

In this method, we checked for the key in the params list, body, and query string. If the key is not found, we return the default value.

Now we can use this method in our controller to get the value of the `name` key from the request body.

```ts
// src/app/users/controllers/create-user.ts

  /**
   * Create a new user
   */
  export default function async createUser(request: Request) {
    const name = request.input('name');

    return {
      name
    };
  }
```

## Request All

The `all` method will return all the data from the request body, query string, and URL parameters.

```ts
// src/core/http/request.ts

  /**
   * Get all the data from the request body, query or params
   */

  /**
   * Get all inputs from the request body, query or params
   */
  public all() {
    const body: any = {};

    for (const key in this.request.body) {
      body[key] = this.request.body[key].value;
    }

    return {
      ...this.request.params,
      ...body,
      ...this.request.query,
    };
  }
```

We can also expose the `params`, `body`, and `query` properties to get the data from each of them.

```ts
// src/core/http/request.ts

  /**
   * Get the request params
   */
  public get params() {
    return this.request.params;
  }

  /**
   * Get the request body
   */
  public get body() {
    const body: any = {};

    for (const key in this.request.body) {
      body[key] = this.request.body[key].value;
    }

    return body;
  }

  /**
   * Get the request query
   */
  public get query() {
    return this.request.query;
  }
```

Now we can update or `all` and `input` methods again to use the `body` property.

```ts
  /**
   * Get all inputs from the request body, query or params
   */
  public all() {
    return {
      ...this.request.params,
      ...this.body,
      ...this.request.query,
    };
  }
  
  /**
   * Get the value of the given key from the request body, query or params
   */
  public input(key: string, defaultValue?: any) {
    return (
      this.request.params[key] ||
      this.body[key] ||
      this.request.query[key] ||
      defaultValue
    );
  }
```

## Request Boolean Input

Let's add a new method that we can call `bool` to make sure that we can receive a boolean value from the request.

For example if the url is something like this: `google.com?is_admin=true` we want to make sure that the value of `is_admin` is a boolean.

```ts

  /**
   * Get the boolean value of the given key from the request body, query or params
   */
  public bool(key: string, defaultValue?: boolean = false) {
    const value = this.input(key, defaultValue);

    if (value === 'true') {
      return true;
    }

    if (value === 'false') {
      return false;
    }

    return Boolean(value);
  }
```

## Request Integer Input

We can also add a method to get an integer value from the request.

```ts
  /**
   * Get the integer value of the given key from the request body, query or params
   */
  public int(key: string, defaultValue = 0) {
    const value = this.input(key, defaultValue);

    return parseInt(value);
  }
```

## Request Float Input

We can also add a method to get a float value from the request.

```ts
  /**
   * Get the float value of the given key from the request body, query or params
   */
  public float(key: string, defaultValue = 0) {
    const value = this.input(key, defaultValue);

    return parseFloat(value);
  }
```

## Request Number Input

We can also add a method to get a number value from the request.

```ts
  /**
   * Get the number value of the given key from the request body, query or params
   */
  public number(key: string, defaultValue = 0) {
    const value = this.input(key, defaultValue);

    return Number(value);
  }
```

## Request File Input

Now let's head to the big boss input, the `file` input, this one will have a special treatment as we'll create a new class handler for that file, we'll call it `UploadedFile` but let's first create the `file` method

```ts
  /**
   * Get the file value of the given key from the request body, query or params
   */
  public file(key: string) {
    return this.request.body[key];
  }
```

Here we'll have a little problem, the file itself is stored in another key than the `value` that we used in the `body` which is called `file`, so we need to make a small modification about that first in our `body` property.

```ts
  /**
   * Get the request body
   */
  public get body() {
    const body: any = {};

    for (const key in this.request.body) {
      const data = this.request.body[key];

      if (data.file) {
        body[key] = {
          file: data.file,
          filename: data.filename,
          mimetype: data.mimetype,
        };
      } else {
        body[key] = data.value;
      }
    }

    return body;
  }
```

As we can see the multipart plugin provides us with some extra data about the file like the file name and its mimetype so we can catch these too.

## Watchout for the array of inputs

Let's hold the files for a moment, imagine with me that you're receiving an array of values of the same key, for example `tags` which is an array of strings, so the request will look like this:

```bash
tags[]: tag1
tags[]: tag2
tags[]: tag3
```

> Please keep in mind that we're still managing the multipart form data, there will be also a json handling next.

Now these values will be sent in one key called `tags[]` and it will sent as an array instead.

Now we have to check if the data from the body is an array or not, if so then handle it as an array, otherwise handle it as a single value.

```ts
  /**
   * Get the request body
   */
  public get body() {
    const body: any = {};

    for (const key in this.request.body) {
      const data = this.request.body[key];

      if (Array.isArray(data)) {
        body[key] = data.map(this.parseBodyValue.bind(this));
      } else {
        body[key] = this.parseBodyValue(data);
      }

    return body;
  }
```

Wait!  `parseBodyValue`, what? this method will just use now to handle the given data properly, so we don't have to repeat our code again, as we can see we'll use it in the map to convert the request body data into proper data, and it is not an array then we'll call it directly.

```ts
  /**
   * Parse the body value
   */
  private parseBodyValue(data: any) {
    if (data.file) {
      return {
        file: data.file,
        filename: data.filename,
        mimetype: data.mimetype,
      };
    }

    return data.value;
  }
```

If the request body content is `json`, then the data will be returned directly, so we can just return it as it is.

```ts
  /**
   * Parse the body value
   */
  private parseBodyValue(data: any) {
    if (data.file) {
      return {
        file: data.file,
        filename: data.filename,
        mimetype: data.mimetype,
      };
    }

    return data.value || data;
  }
```

## Uploaded File

This is where we'll stop for this article, we'll continue in the next article to handle the `UploadedFile` class.

## 🎨 Project Repository

You can find the latest updates of this project on [Github](https://github.com/hassanzohdy/nodejs-2023)

## 😍 Join our community

Join our community on [Discord](https://discord.gg/pb2vmdfhGf) to get help and support (Node Js 2023 Channel).

## 🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on [Youtube](https://www.youtube.com/playlist?list=PLGO8ntvxgiZMJc7RN2lIq9WmMOlWZGzmz), the course is in Arabic language.

## 💰 Bonus Content 💰

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

- [Event Driven Architecture: A Practical Guide in Javascript](https://dev.to/hassanzohdy/event-driven-architecture-the-best-paradigm-that-i-love-to-work-with-in-javascript-and-node-js-1gnk)
- [Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript](https://dev.to/hassanzohdy/best-practices-for-case-styles-camel-pascal-snake-and-kebab-case-in-node-and-javascript-55oi)
- [After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
](https://dev.to/hassanzohdy/after-6-years-of-practicing-mongodb-here-are-my-thoughts-on-mongodb-vs-mysql-574b)

Packages & Libraries

- [Collections: Your ultimate Javascript Arrays Manager](https://dev.to/hassanzohdy/collections-your-ultimate-javascript-array-handler-3o15)
- [Supportive Is: an elegant utility to check types of values in JavaScript](https://dev.to/hassanzohdy/supportive-is-an-elegant-utility-to-check-types-of-values-in-javascript-1b3e)
- [Localization: An agnostic i18n package to manage localization in your project](https://dev.to/hassanzohdy/mongez-localization-the-simplest-way-to-translate-your-website-regardless-your-favorite-framework-4gi3)

 React Js Packages

- [useFetcher: easiest way to fetch data in React Js](https://dev.to/hassanzohdy/usefetcher-the-easiest-way-to-fetch-data-in-react-45o9)

Courses (Articles)

- [React Js: Let"s Create File Manager With React Js and Node Js](https://dev.to/hassanzohdy/lets-create-a-file-manager-from-scratch-with-react-and-typescript-chapter-i-a-good-way-to-expand-your-experience-5g4k)