我正在尝试在this tutorial之后使用REST Api构建一个Angular 7 CRUD应用程序 .

简单地说它是一个经典的显示产品,添加,编辑和所有爵士有点应用程序 .

Rest API使用Mongoose,Express和Node制作 . Angular App和服务器都可以自行运行 .

当我在cmd中使用mongod时它正在等待一个答案,并且在api中的npm start它确实连接成功 .

关于应用程序的一切工作也没有编译错误 .

但是应用程序似乎根本没有连接到api,当我尝试将产品添加到空列表时,它只是继续加载而不再继续 .

这是我的服务打字稿文件:

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<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // 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<Product[]> {
    return this.http.get<Product[]>(apiUrl)
      .pipe(
        tap(heroes => console.log('fetched products')),
        catchError(this.handleError('getProducts', []))
      );
  }

  getProduct(id: number): Observable<Product> {
    const url = `${apiUrl}/${id}`;
    return this.http.get<Product>(url).pipe(
      tap(_ => console.log(`fetched product id=${id}`)),
      catchError(this.handleError<Product>(`getProduct id=${id}`))
    );
  }

  addProduct(product): Observable<Product> {
    return this.http.post<Product>(apiUrl, product, httpOptions).pipe(
      tap((product: Product) => console.log(`added product w/ id=${product._id}`)),
      catchError(this.handleError<Product>('addProduct'))
    );
  }
  updateProduct(id, product): Observable<any> {
    const url = `${apiUrl}/${id}`;
    return this.http.put(url, product, httpOptions).pipe(
      tap(_ => console.log(`updated product id=${id}`)),
      catchError(this.handleError<any>('updateProduct'))
    );
  }

  deleteProduct(id): Observable<Product> {
    const url = `${apiUrl}/${id}`;

    return this.http.delete<Product>(url, httpOptions).pipe(
      tap(_ => console.log(`deleted product id=${id}`)),
      catchError(this.handleError<Product>('deleteProduct'))
    );
  }
}

这是api的app.js文件:

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(() =>  console.log('connection successful'))
  .catch((err) => 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;

我目前没有任何错误报告要分享,如果您需要更多代码,我会尽快提供 .

提前致谢 !

编辑:我称之为服务的产品添加组件:

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 => {
        let id = res['_id'];
        this.isLoadingResults = false;
        this.router.navigate(['/product-details', id]);
      }, (err) => {
        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]
    });
  }

}

编辑2:一些我最初没有找到的错误日志,当访问应用程序并且它试图从服务器显示列表时:

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: "<!DOCTYPE html>↵<html lang="en">↵<head>↵<meta charset="utf-8">↵<title>Error</title>↵</head>↵<body>↵<pre>Cannot GET /api/v1/products</pre>↵</body>↵</html>↵"
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

我尝试添加新产品时得到的那个:

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)

和products.js文件:

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;