In this tutorial, we will be using TypeScript on both sides (server and client) to build a Todo App from scratch with React, NodeJS, Express, and MongoDB.

So, let’s start by planning the API.

  • API with NodeJS, Express, MongoDB and TypeScript
  • Setting up
  • Create a Todo Type
  • Create a Todo Model
  • Create API controllers
  • Get, Add, Update and Delete Todos
  • Create API routes
  • Create a Server
  • Client-side with React and TypeScript
  • Setting up
  • Create a Todo Type
  • Fetch data from the API
  • Create the components
  • Add Todo Form
  • Display a Todo
  • Fetch and Display data
  • Resources

Let’s dive in.

API with NodeJS, Express, MongoDB and TypeScript

Getting set up

To create a new NodeJS App, you need to run this command on the terminal:

  yarn init

It will ask for a couple of questions and then initialize the app. You can skip it by adding a -y flag to the command.

Next, structure the project as follows:

├── dist
├── node_modules
├── src
   ├── app.ts
   ├── controllers
   |  └── todos
   |     └── index.ts
   ├── models
   |  └── todo.ts
   ├── routes
   |  └── index.ts
   └── types
      └── todo.ts
├── nodemon.json
├── package.json
├── tsconfig.json

As you can see, this file structure is relatively simple. The dist directory will serve as an output folder once the code has compiled to plain JavaScript.

We also have an app.ts file that is the entry point of the server. The controllers, types, and routes are also in their respective folder names.

Now, we need to configure the tsconfig.json file to help the compiler along following our preferences.

  • tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "dist/js",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["src/types/*.ts", "node_modules", ".vscode"]
}

Here we have four main properties to underline:

outDir: tells the compiler to put the compiled code into the dist/js folder.

rootDir: informs TypeScript to compile every .ts file located in the src folder.

include: tells the compiler to include files that are in the src directory and sub-directory.

exclude: will exclude the files or folders passed in the array during compile-time.

We can now install the dependencies to enable TypeScript in the project. Because by default, this app will use JavaScript.

There are two ways of using TypeScript in a NodeJS app. Either locally in the project or globally in our machine. I will go for the latter based on personal preference, but you can stick with the local way if you want too.

Now, let’s execute the following command on the terminal to install TypeScript.

  yarn add typescript -g

This g flag allows installing TypeScript globally and this makes it accessible from anywhere on the computer.

Next, let’s add some dependencies in order to use Express and MongoDB.

  yarn add express cors mongoose

We also need to install their types as development dependencies to help the TypeScript compiler understand the packages.

  yarn add -D @types/node @types/express @types/mongoose @types/cors

Now, TypeScript won’t yell at you anymore - it will use these types to define the libraries we’ve just installed.

We also need to add other dependencies to be able to compile the TypeScript code and start the server concurrently.

  yarn add -D concurrently nodemon

With that in place, we can now update the package.json file with the scripts needed to start the server.

  • package.json
  "scripts": {
    "build": "tsc",
    "start": "concurrently \"tsc -w\" \"nodemon dist/js/app.js\""
  }

concurrently will help compile the TypeScript code, keep watching for changes, and also start the server simultaneously. That said, we can now launch the server - however, we have not created something meaningful yet in that regard. So, let’s fix that in the next section.

Create a Todo Type

  • types/todo.ts
import { Document } from "mongoose"

export interface ITodo extends Document {
  name: string
  description: string
  status: boolean
}

Here, we have a Todo interface that extends the Document type provided by mongoose. We will be using it later to interact with MongoDB. That said, we can now define how a Todo model should look.

Create a Todo Model

  • models/todo.ts
import { ITodo } from "./../types/todo"
import { model, Schema } from "mongoose"

const todoSchema: Schema = new Schema(
  {
    name: {
      type: String,
      required: true,
    },

    description: {
      type: String,
      required: true,
    },

    status: {
      type: Boolean,
      required: true,
    },
  },
  { timestamps: true }
)

export default model<ITodo>("Todo", todoSchema)

As you can see here, we start by importing the interface ITodo and some utilities from mongoose. The latter helps to define the Todo schema and also pass in ITodo as a type to the model before exporting it.

With that, we can now use the Todo model in other files to interact with the database.

#typescript #react #node #mongodb #developer

How to Build a Todo App with React, TypeScript, NodeJS and MongoDB
31.35 GEEK