title: Angular 7 CRUD App Service not connecting to REST Api
body: <p>I'm trying to build an Angular 7 CRUD app with a REST Api following <a href="https://www.djamware.com/post/5bca67d780aca7466989441f/angular-7-tutorial-building-crud-web-application#ch4" rel="nofollow noreferrer">this tutorial</a>.</p>
  
  <p>Simply put it's a classic display products , add , edit and all that jazz kinda app.</p>
  
  <p>The Rest API is made using Mongoose, Express and Node. Both the Angular App and the server are running fine on their own.</p>
  
  <p>When I use mongod in the cmd it's waiting for an answer , and with the npm start in the api it does connect successfully.</p>
  
  <p>Everything about the App works too without compilation errors.</p>
  
  <p>But the app doesn't seem to be connected to the api at all , when I try to add a product to the empty list it just keeps on loading without going any further.</p>
  
  <p>This is the service typescript file that I have :</p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { Observable, of, throwError } from 'rxjs';
  import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
  import { catchError, tap, map } from 'rxjs/operators';
  import { Product } from './products';
  
  const httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };
  const apiUrl = "/api/v1/products";
  
  @Injectable({
    providedIn: 'root'
  })
  export class ApiService {
  
    constructor(private http: HttpClient) { }
    private handleError&lt;T&gt;(operation = 'operation', result?: T) {
      return (error: any): Observable&lt;T&gt; =&gt; {
  
        // TODO: send the error to remote logging infrastructure
        console.error(error); // log to console instead
  
        // Let the app keep running by returning an empty result.
        return of(result as T);
      };
    }
    getProducts(): Observable&lt;Product[]&gt; {
      return this.http.get&lt;Product[]&gt;(apiUrl)
        .pipe(
          tap(heroes =&gt; console.log('fetched products')),
          catchError(this.handleError('getProducts', []))
        );
    }
  
    getProduct(id: number): Observable&lt;Product&gt; {
      const url = `${apiUrl}/${id}`;
      return this.http.get&lt;Product&gt;(url).pipe(
        tap(_ =&gt; console.log(`fetched product id=${id}`)),
        catchError(this.handleError&lt;Product&gt;(`getProduct id=${id}`))
      );
    }
  
    addProduct(product): Observable&lt;Product&gt; {
      return this.http.post&lt;Product&gt;(apiUrl, product, httpOptions).pipe(
        tap((product: Product) =&gt; console.log(`added product w/ id=${product._id}`)),
        catchError(this.handleError&lt;Product&gt;('addProduct'))
      );
    }
    updateProduct(id, product): Observable&lt;any&gt; {
      const url = `${apiUrl}/${id}`;
      return this.http.put(url, product, httpOptions).pipe(
        tap(_ =&gt; console.log(`updated product id=${id}`)),
        catchError(this.handleError&lt;any&gt;('updateProduct'))
      );
    }
  
    deleteProduct(id): Observable&lt;Product&gt; {
      const url = `${apiUrl}/${id}`;
  
      return this.http.delete&lt;Product&gt;(url, httpOptions).pipe(
        tap(_ =&gt; console.log(`deleted product id=${id}`)),
        catchError(this.handleError&lt;Product&gt;('deleteProduct'))
      );
    }
  }
  </code></pre>
  
  <p>This is the app.js file for the api:</p>
  
  <pre><code>var express = require('express');
  var path = require('path');
  var favicon = require('serve-favicon');
  var logger = require('morgan');
  var cookieParser = require('cookie-parser');
  var bodyParser = require('body-parser');
  var mongoose = require('mongoose');
  var restful = require('node-restful');
  var methodOverride = require('method-override');
  var cors = require('cors');
  
  var index = require('./routes/index');
  var users = require('./routes/users');
  var products = require('./routes/products');
  var app = express();
  
  mongoose.Promise = global.Promise;
  
  mongoose.connect('mongodb://localhost/product')
    .then(() =&gt;  console.log('connection successful'))
    .catch((err) =&gt; console.error(err));
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'ejs');
  
  // uncomment after placing your favicon in /public
  //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
  app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({'extended':'true'}));
  app.use(bodyParser.json({type:'application/vnd.api+json'}));
  app.use(methodOverride());
  app.use(cookieParser());
  app.use(express.static(path.join(__dirname, 'public')));
  
  app.use(cors());
  app.use('/', index);
  app.use('/users', users);
  app.use('/api/v1/products', products);
  
  var Category = app.resource = restful.model('category', mongoose.Schema({
    cat_name: String,
  }))
  .methods(['get', 'post', 'put', 'delete']);
  
  Category.register(app, '/category');
  
  // catch 404 and forward to error handler
  app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
  });
  
  // error handler
  app.use(function(err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
  
    // render the error page
    res.status(err.status || 500);
    res.json(err.message);
  });
  
  module.exports = app;
  </code></pre>
  
  <p>I don't have any error report to share at the moment, if you need more from the code I'll provide it as soon as I can.</p>
  
  <p>Thanks in advance !</p>
  
  <p>EDIT : The product-add component where I call the service :</p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  import { Router } from '@angular/router';
  import { ApiService } from '../api.service';
  import { FormControl, FormGroupDirective, FormBuilder, FormGroup, NgForm, Validators } from '@angular/forms';
  
  @Component({
    selector: 'app-product-add',
    templateUrl: './product-add.component.html',
    styleUrls: ['./product-add.component.css']
  })
  export class ProductAddComponent implements OnInit {
  
    productForm: FormGroup;
    prod_name: string = '';
    prod_desc: string = '';
    prod_price: number = null;
    updated_at: Date = null;
    isLoadingResults = false;
  
    onFormSubmit(form: NgForm) {
      this.isLoadingResults = true;
      this.api.addProduct(form)
        .subscribe(res =&gt; {
          let id = res['_id'];
          this.isLoadingResults = false;
          this.router.navigate(['/product-details', id]);
        }, (err) =&gt; {
          console.log(err);
          this.isLoadingResults = false;
        });
    }
  
    constructor(private router: Router, private api: ApiService, private formBuilder: FormBuilder) { }
  
    ngOnInit() {
      this.productForm = this.formBuilder.group({
        'prod_name': [null, Validators.required],
        'prod_desc': [null, Validators.required],
        'prod_price': [null, Validators.required],
        'updated_at': [null, Validators.required]
      });
    }
  
  }
  </code></pre>
  
  <p>EDIT 2 : Some error logs that I didn't find at first , when accessing the app and it's trying to display a list from the server : </p>
  
  <pre><code>Angular is running in the development mode. Call enableProdMode() to enable the production mode.
  zone.js:2969 GET http://localhost:4200/api/v1/products 404 (Not Found)
  scheduleTask    @   zone.js:2969
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask  @   zone.js:407
  onScheduleTask  @   zone.js:297
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask  @   zone.js:401
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask  @   zone.js:232
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @   zone.js:255
  scheduleMacroTaskWithCurrentZone    @   zone.js:1114
  (anonymous) @   zone.js:3001
  proto.(anonymous function)  @   zone.js:1394
  (anonymous) @   http.js:1630
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe  @   Observable.js:43
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:29
  (anonymous) @   subscribeTo.js:21
  subscribeToResult   @   subscribeToResult.js:11
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub  @   mergeMap.js:74
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext   @   mergeMap.js:68
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next  @   mergeMap.js:51
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next   @   Subscriber.js:54
  (anonymous) @   scalar.js:5
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe  @   Observable.js:43
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:29
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call @   mergeMap.js:29
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call @   filter.js:15
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call   @   map.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/tap.js.DoOperator.call    @   tap.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchOperator.call  @   catchError.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe  @   Observable.js:24
  push../src/app/products/products.component.ts.ProductsComponent.ngOnInit    @   products.component.ts:20
  checkAndUpdateDirectiveInline   @   core.js:18668
  checkAndUpdateNodeInline    @   core.js:19932
  checkAndUpdateNode  @   core.js:19894
  debugCheckAndUpdateNode @   core.js:20528
  debugCheckDirectivesFn  @   core.js:20488
  (anonymous) @   ProductsComponent_Ho…gfactory.js? [sm]:1
  debugUpdateDirectives   @   core.js:20480
  checkAndUpdateView  @   core.js:19876
  callViewAction  @   core.js:20117
  execEmbeddedViewsAction @   core.js:20080
  checkAndUpdateView  @   core.js:19877
  callViewAction  @   core.js:20117
  execComponentViewsAction    @   core.js:20059
  checkAndUpdateView  @   core.js:19882
  callWithDebugContext    @   core.js:20770
  debugCheckAndUpdateView @   core.js:20448
  push../node_modules/@angular/core/fesm5/core.js.ViewRef_.detectChanges  @   core.js:18257
  (anonymous) @   core.js:14919
  push../node_modules/@angular/core/fesm5/core.js.ApplicationRef.tick @   core.js:14919
  (anonymous) @   core.js:14810
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke    @   zone.js:388
  onInvoke    @   core.js:14191
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke    @   zone.js:387
  push../node_modules/zone.js/dist/zone.js.Zone.run   @   zone.js:138
  push../node_modules/@angular/core/fesm5/core.js.NgZone.run  @   core.js:14105
  next    @   core.js:14810
  schedulerFn @   core.js:10206
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub   @   Subscriber.js:196
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next   @   Subscriber.js:134
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next  @   Subscriber.js:77
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next   @   Subscriber.js:54
  push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @   Subject.js:47
  push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit   @   core.js:10190
  checkStable @   core.js:14160
  onHasTask   @   core.js:14204
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.hasTask   @   zone.js:441
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate._updateTaskCount  @   zone.js:461
  push../node_modules/zone.js/dist/zone.js.Zone._updateTaskCount  @   zone.js:285
  push../node_modules/zone.js/dist/zone.js.Zone.runTask   @   zone.js:205
  drainMicroTaskQueue @   zone.js:595
  Promise.then (async)        
  scheduleMicroTask   @   zone.js:578
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask  @   zone.js:410
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask  @   zone.js:232
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask @   zone.js:252
  scheduleResolveOrReject @   zone.js:862
  ZoneAwarePromise.then   @   zone.js:962
  push../node_modules/@angular/core/fesm5/core.js.PlatformRef.bootstrapModule @   core.js:14691
  ./src/main.ts   @   main.ts:12
  __webpack_require__ @   bootstrap:78
  0   @   main.ts:13
  __webpack_require__ @   bootstrap:78
  checkDeferredModules    @   bootstrap:45
  webpackJsonpCallback    @   bootstrap:32
  (anonymous) @   main.js:1
  api.service.ts:22 
  HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/api/v1/products", ok: false, …}
  error: "&lt;!DOCTYPE html&gt;↵&lt;html lang="en"&gt;↵&lt;head&gt;↵&lt;meta charset="utf-8"&gt;↵&lt;title&gt;Error&lt;/title&gt;↵&lt;/head&gt;↵&lt;body&gt;↵&lt;pre&gt;Cannot GET /api/v1/products&lt;/pre&gt;↵&lt;/body&gt;↵&lt;/html&gt;↵"
  headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
  message: "Http failure response for http://localhost:4200/api/v1/products: 404 Not Found"
  name: "HttpErrorResponse"
  ok: false
  status: 404
  statusText: "Not Found"
  url: "http://localhost:4200/api/v1/products"
  __proto__: HttpResponseBase
  </code></pre>
  
  <p>Also the one I get when I try to add a new product : </p>
  
  <pre><code>zone.js:2969 POST http://localhost:4200/api/v1/products 404 (Not Found)
  scheduleTask @ zone.js:2969
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
  onScheduleTask @ zone.js:297
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:401
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:255
  scheduleMacroTaskWithCurrentZone @ zone.js:1114
  (anonymous) @ zone.js:3001
  proto.(anonymous function) @ zone.js:1394
  (anonymous) @ http.js:1630
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe @ Observable.js:43
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:29
  (anonymous) @ subscribeTo.js:21
  subscribeToResult @ subscribeToResult.js:11
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js:74
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js:68
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js:51
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
  (anonymous) @ scalar.js:5
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe @ Observable.js:43
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:29
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call @ mergeMap.js:29
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call @ filter.js:15
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call @ map.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/tap.js.DoOperator.call @ tap.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchOperator.call @ catchError.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../src/app/product-add/product-add.component.ts.ProductAddComponent.onFormSubmit @ product-add.component.ts:23
  (anonymous) @ ProductAddComponent.html:10
  handleEvent @ core.js:19676
  callWithDebugContext @ core.js:20770
  debugHandleEvent @ core.js:20473
  dispatchEvent @ core.js:17125
  (anonymous) @ core.js:18615
  schedulerFn @ core.js:10218
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:196
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:134
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:77
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
  push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:47
  push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:10190
  push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.onSubmit @ forms.js:4647
  (anonymous) @ ProductAddComponent.html:10
  handleEvent @ core.js:19676
  callWithDebugContext @ core.js:20770
  debugHandleEvent @ core.js:20473
  dispatchEvent @ core.js:17125
  (anonymous) @ core.js:17572
  (anonymous) @ platform-browser.js:993
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
  onInvokeTask @ core.js:14182
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:420
  push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
  push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496
  invokeTask @ zone.js:1540
  globalZoneAwareCallback @ zone.js:1566
  api.service.ts:22 HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/api/v1/products", ok: false, …}
  (anonymous) @ api.service.ts:22
  push../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchSubscriber.error @ catchError.js:34
  push../node_modules/rxjs/_esm5/internal/operators/tap.js.TapSubscriber._error @ tap.js:61
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ Subscriber.js:60
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error @ Subscriber.js:80
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ Subscriber.js:60
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error @ Subscriber.js:80
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ Subscriber.js:60
  push../node_modules/rxjs/_esm5/internal/OuterSubscriber.js.OuterSubscriber.notifyError @ OuterSubscriber.js:13
  push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._error @ InnerSubscriber.js:18
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ Subscriber.js:60
  onLoad @ http.js:1547
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
  onInvokeTask @ core.js:14182
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:420
  push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
  push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496
  invokeTask @ zone.js:1540
  globalZoneAwareCallback @ zone.js:1566
  error (async)
  customScheduleGlobal @ zone.js:1666
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
  onScheduleTask @ zone.js:297
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:401
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
  push../node_modules/zone.js/dist/zone.js.Zone.scheduleEventTask @ zone.js:258
  (anonymous) @ zone.js:1831
  (anonymous) @ http.js:1619
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe @ Observable.js:43
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:29
  (anonymous) @ subscribeTo.js:21
  subscribeToResult @ subscribeToResult.js:11
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub @ mergeMap.js:74
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js:68
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js:51
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
  (anonymous) @ scalar.js:5
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe @ Observable.js:43
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:29
  push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call @ mergeMap.js:29
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterOperator.call @ filter.js:15
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call @ map.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/tap.js.DoOperator.call @ tap.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchOperator.call @ catchError.js:18
  push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe @ Observable.js:24
  push../src/app/product-add/product-add.component.ts.ProductAddComponent.onFormSubmit @ product-add.component.ts:23
  (anonymous) @ ProductAddComponent.html:10
  handleEvent @ core.js:19676
  callWithDebugContext @ core.js:20770
  debugHandleEvent @ core.js:20473
  dispatchEvent @ core.js:17125
  (anonymous) @ core.js:18615
  schedulerFn @ core.js:10218
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:196
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:134
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:77
  push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
  push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:47
  push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:10190
  push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.onSubmit @ forms.js:4647
  (anonymous) @ ProductAddComponent.html:10
  handleEvent @ core.js:19676
  callWithDebugContext @ core.js:20770
  debugHandleEvent @ core.js:20473
  dispatchEvent @ core.js:17125
  (anonymous) @ core.js:17572
  (anonymous) @ platform-browser.js:993
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
  onInvokeTask @ core.js:14182
  push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:420
  push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
  push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496
  invokeTask @ zone.js:1540
  globalZoneAwareCallback @ zone.js:1566
  core.js:12632 ERROR TypeError: Cannot read property '_id' of undefined
      at SafeSubscriber._next (product-add.component.ts:24)
      at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196)
      at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134)
      at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77)
      at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
      at CatchSubscriber.push../node_modules/rxjs/_esm5/internal/OuterSubscriber.js.OuterSubscriber.notifyNext (OuterSubscriber.js:10)
      at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:15)
      at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
      at subscribeTo.js:16
      at subscribeToResult (subscribeToResult.js:11)
  </code></pre>
  
  <p>And the products.js file :</p>
  
  <pre><code>var express = require('express');
  var router = express.Router();
  var mongoose = require('mongoose');
  var Product = require('../models/Product.js');
  
  /* GET ALL PRODUCTS */
  router.get('/', function(req, res, next) {
    Product.find(function (err, products) {
      if (err) return next(err);
      res.json(products);
    });
  });
  
  /* GET SINGLE PRODUCT BY ID */
  router.get('/:id', function(req, res, next) {
    Product.findById(req.params.id, function (err, post) {
      if (err) return next(err);
      res.json(post);
    });
  });
  
  /* SAVE PRODUCT */
  router.post('/', function(req, res, next) {
    Product.create(req.body, function (err, post) {
      if (err) return next(err);
      res.json(post);
    });
  });
  
  /* UPDATE PRODUCT */
  router.put('/:id', function(req, res, next) {
    Product.findByIdAndUpdate(req.params.id, req.body, function (err, post) {
      if (err) return next(err);
      res.json(post);
    });
  });
  
  /* DELETE PRODUCT */
  router.delete('/:id', function(req, res, next) {
    Product.findByIdAndRemove(req.params.id, req.body, function (err, post) {
      if (err) return next(err);
      res.json(post);
    });
  });
  
  module.exports = router;
  </code></pre>