title: BodyParser doesn't parse - but everything looks right to me. How to resolve `Cannot read property of undefined`
body: <p>I cannot for the life of me figured why the post route to <code>localhost:3000/api/v1/projects/add</code> doesn't successfully save to the database. All other routes work, but the post route to "/add" returns a 500 internal server error. Saying that <code>TypeError: Cannot read property 'title' of undefined</code>. </p>
  
  <p>And the console also throw and CORB error:</p>
  
  <p><code>Cross-Origin Read Blocking (CORB) blocked cross-origin response http://localhost:3000/api/v1/projects/add with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.</code></p>
  
  <p>The correct object it send from the Angular <code>admin.service.ts</code> <code>saveProject()</code> method when I <code>console.log(projectFormData)</code> but something is clearly wrong on the receiving end since <code>req.body</code> cannot be parsed. And it app.js bodyParser seems to be to be loaded in the correct order before the routes.</p>
  
  <p>Can someone spot the mistake.</p>
  
  <p>All help is very much appreciated.</p>
  
  <p><strong>Express app.</strong></p>
  
  <p><strong>app.js</strong></p>
  
  <pre><code>var express = require("express");
  var helmet = require("helmet");
  var path = require("path");
  var cookieParser = require("cookie-parser");
  var bodyParser = require("body-parser");
  var mongoose = require("mongoose");
  
  // MongoDB connection
  mongoose.connect("mongodb://localhost:27017/mydb", {
    useNewUrlParser: true
  });
  
  // Router
  var users = require("./routes/users");
  var projects = require("./routes/projects");
  
  var app = express();
  app.use(helmet());
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(cookieParser());
  
  // CORS
  app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "DELETE, PUT, GET, POST");
    res.header(
      "Access-Control-Allow-Headers",
      "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    );
    if (req.method === "OPTIONS") {
      res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET");
      return res.status(200).json({});
    }
    next();
  });
  
  // Routes
  app.use("/api/v1/users", users);
  app.use("/api/v1/projects", projects);
  
  module.exports = app;
  </code></pre>
  
  <p><strong>routes/projects.js</strong></p>
  
  <pre><code>var express = require("express");
  var Project = require("../models/project");
  
  var router = express.Router();
  
  router.get("/", function(req, res, next) {
    Project.find({})
      .exec()
      .then(result =&gt; res.json(result));
  });
  
  router.get("/:id", function(req, res, next) {
    Project.findById(req.params.id)
      .exec()
      .then(result =&gt; res.json(result));
  });
  
  router.post("/add", function(res, req, next) {
    var project = new Project({
      title: req.body.title,
      description: req.body.description
    });
    project
      .save()
      .then(function(result) {
        res.status(201).json({
          message: "Successfully created new project",
          result: result
        });
      })
      .catch(function(err) {
        res.status(500).json({ error: err });
      });
  });
  
  module.exports = router;
  </code></pre>
  
  <p>Angular client app</p>
  
  <p><strong>app/admin/add-project/add-project.component.ts</strong></p>
  
  <pre><code>import { Component } from '@angular/core';
  import { FormBuilder, Validators } from '@angular/forms';
  import { Project } from '../../shared/project';
  import { AdminService } from '../admin.service';
  
  @Component({
    selector: 'app-add-project',
    templateUrl: './add-project.component.html',
    styleUrls: ['./add-project.component.css']
  })
  export class AddProjectComponent {
    projectForm = this.formBuilder.group({
      title: ['', Validators.required],
      description: ['', Validators.required]
    });
  
    constructor(
      private formBuilder: FormBuilder,
      private adminService: AdminService
    ) {}
  
    onSubmit() {
      this.adminService.saveProject(
        this.projectForm.value.title,
        this.projectForm.value.description
      );
    }
  }
  </code></pre>
  
  <p><strong>app/admin/admin.service.ts</strong></p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { HttpClient } from '@angular/common/http';
  import { Project } from '../shared/project';
  
  @Injectable({
    providedIn: 'root'
  })
  export class AdminService {
    saveProject(title: string, description: string) {
      const projectFormData: Project = { title, description };
      console.log(projectFormData);
      this.http
        .post&lt;Project&gt;(
          'http://localhost:3000/api/v1/projects/add',
          projectFormData
        )
        .subscribe(result =&gt; console.log(result));
    }
  
    constructor(private http: HttpClient) {}
  }
  </code></pre>
  
  <hr>
  
  <p>postman</p>
  
  <pre><code>POST /api/v1/projects/add HTTP/1.1
  Host: localhost:3000
  Content-Type: application/json
  User-Agent: PostmanRuntime/7.15.2
  Accept: */*
  Cache-Control: no-cache
  Postman-Token: cc6fd8d2-28c0-4ae7-9392-8602b9c8f401,e814d578-03ce-472d-be70-86f0e7b37373
  Host: localhost:3000
  Accept-Encoding: gzip, deflate
  Content-Length: 62
  Connection: keep-alive
  cache-control: no-cache
  
  {
      "title": "postman",
      "description": "this is the postman"
  }
  </code></pre>
  
  <p>Response</p>
  
  <pre><code>TypeError: Cannot read property 'title' of undefined
  
  HTTP/1.1 500 Internal Server Error
  X-DNS-Prefetch-Control: off
  X-Frame-Options: SAMEORIGIN
  Strict-Transport-Security: max-age=15552000; includeSubDomains
  X-Download-Options: noopen
  X-Content-Type-Options: nosniff
  X-XSS-Protection: 1; mode=block
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Methods: DELETE, PUT, GET, POST
  Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
  Content-Security-Policy: default-src 'none'
  Content-Type: text/html; charset=utf-8
  Content-Length: 2242
  Date: Fri, 16 Aug 2019 11:04:34 GMT
  Connection: close
  </code></pre>