Req.Body是Angular 2表单提交+ Bodyparser

时间:2017-01-04 15:31:25

标签: node.js mongodb angular express mongoose

我的应用程序中有一个被动(模型驱动)表单,我无法将表单数据传递给mongoose。当我通过http post方法提交数据时,我不断收到错误,因为后端正在接收一个空对象。

我知道后端有效,因为当我向Postman提交帖子请求时,我得到的结果状态为“201 Created”。我一直在阅读过去几个论坛和各种博客几天,我仍然难过。

问题

  1. 我需要更改什么才能让表单数据到达后端 适当?
  2. Angular2 Form数据提交是否有最佳实践?
  3. 备注 看起来可能缺少某些内容,例如URL,您会注意到表单中的一些其他字段。我故意没有将所有这些都包括在内,以简明扼要地混淆了我后端的实际链接。

    后端 - 猫鼬

    jobs.controllers.js

    var mongoose = require('mongoose');
    var Job = mongoose.model('Job');
    module.exports.addNewJob = function(req, res){
      console.log(req.body);//added to see req payload from client
      Job
            .create({
                _id: req.body.jobid,
                desc: req.body.name,
                type: req.body.jobType,
                location: req.body.location
            },function(err, job){
                if(err){
                    console.log("Error creating job");
                    res
                        .status(400)
                        .json(err);
                }else{
                    console.log("Job Created", job);
                    res
                        .status(201)
                        .json(job);
                }
            });
    }
    

    jobs.model.js

    var mongoose = require('mongoose');
    var jobSchema = new mongoose.Schema({
        _id: {
            type: String
        },
        desc: {
            type: String
        },
        type: {
            type: String,
            default: "TM"
        },
        location: String
    });
    mongoose.model('Job', jobSchema);
    

    db.js

    var mongoose = require ('mongoose');
    var dburl = 'mongodb://localhost:27017/dbname';
    
    mongoose.connect(dburl);
    
    mongoose.connection.on('connected', function(){
        console.log('Mongoose connected to ' + dburl);
    });
    
    mongoose.connection.on('disconnected', function(){
        console.log('Mongoose disconnedted');
    });
    
    mongoose.connection.on('error', function(err){
        console.log('Mongoose connection error: ' + err);
    });
    
    require('./jobs.model.js');
    

    index.js

    var express = require('express');
    var router = express.Router();
    
    var ctrlJobs = require('../controllers/jobs.controllers.js');
    
    router
        .route('/jobs')
        .get(ctrlJobs.jobsGetAll)
        .post(ctrlJobs.addNewJob);
    
    module.exports = router;
    

    app.js

    require('./api/data/db.js');
    var express = require('express');
    var app = express ();
    var path = require('path');
    var bodyParser = require('body-parser');
    
    var routes = require('./api/routes');
    
    app.use(function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
    });
    
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.use(bodyParser.urlencoded({extended: false}));
    
    app.use('/api', routes);//Goes to index.js
    

    前端 - Angular2 Final

    jobs.service

    import { Injectable } from '@angular/core';
    import { Http, Response, Headers, RequestOptions } from '@angular/http';
    
    import { Observable } from 'rxjs/Rx';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/catch';
    
    
    @Injectable()
    export class JobsService{
        private _url = "http://123.456.789.100/api/jobs"; //removed actual address for post
        constructor(private _http: Http){}
    
        addNewJob(form: Object){
            let headers = new Headers({'Content-Type':'application/json'});
            let options = new RequestOptions({headers: headers});
            return this._http
                    .post(this._url, JSON.stringify(form), options)
                    .map(this.extractData)
                    .catch(this.handleError);
        }
    
        private extractData(res: Response){
            let body = res.json();
            return body.data || { };
        }
    
        private handleError (error: Response | any) {
        let errMsg: string;
        if (error instanceof Response) {
          const body = error.json() || '';
          const err = body.error || JSON.stringify(body);
          errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
          errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
      }
    }
    

    作业-form.component

    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    import { Router, ActivatedRoute } from '@angular/router';
    
    import { JobsService } from './jobs.service';
    
    @Component({
        templateUrl: './job-form.component.html',
        providers: [JobsService]
    })
    
    export class JobFormComponent implements OnInit {
    
        id: string;
        job: any;
        jobForm: FormGroup;
        title: string;
    
        constructor(
            private _fb: FormBuilder,
            private _router: Router,
            private _route: ActivatedRoute,
            private _jobsService: JobsService
            ){
    
            }
    
    
        ngOnInit(): void {
            this.jobForm = this._fb.group({
                    jobid: ['', Validators.required],
                    name: ['', Validators.required],
                    jobType: ['', Validators.required],
                    location: ['', Validators.required]
                });
    
            this.id = this._route.snapshot.params['id'];
    
            this.title = this.id ? "Edit Job" : "Create New Job";
    
        }
    
        save(form: any){
            console.log(this.jobForm.value);
    
            this._jobsService.addNewJob(form).subscribe((dataResponse) => {
                console.log("Submitting" + dataResponse);
            });
        }
        reset(){
            this.jobForm.reset();
        }
    }
    

    作业-form.component.html

    <form [formGroup]="jobForm" novalidate (ngSubmit)="save(jobForm.value)">
                    <div class="row">
                        <div class="col-xs-2">
                            <label>Job Number</label>
                            <input [ngModel]="job?.jobid ? job.jobid : ''" class="form-control" type="text" formControlName="jobid">
                        </div>
                        <div class="col-xs-8">
                            <label>Title</label>
                            <input [ngModel]="job?.name ? job.name : ''" class="form-control" type="text" formControlName="name">
                        </div>
                        <div class="col-xs-2">
                            <label>Type</label><br />
                            <select [ngModel]="job?.jobType ? job.jobType : ''"class="form-control" formControlName="jobType">
                                <option value="TM">T&M</option>
                                <option value="LS">Lump Sum</option>
                            </select>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-xs-2">
                            <label>Status</label><br />
                            <select class="form-control" formControlName="status" [ngModel]="job?.status ? job.status : ''">
                                <option value="Pending">Pending</option>
                                <option value="Active">Active</option>
                                <option value="On Hold">On Hold</option>
                                <option value="Complete">Complete</option>
                                <option value="Closed">Closed</option>
                            </select>
                        </div>
                        <div class="col-xs-5">
                            <label>Location</label>
                            <input [ngModel]="job?.location ? job.location : ''" class="form-control" type="text" formControlName="location">
                        </div>
                    </div>
                   <br />
                    <div class="row">
                        <div class="col-xs-1">
                            <button type="btn btn-primary" class="btn btn-primary" [disabled]="!jobForm.valid">Submit</button>
                        </div>
                        <div class="col-xs-1">
                            <button class="btn btn-default" (click)="reset()">Reset</button>
                        </div>
                    </div>
                </form>
    

    测试

    将标题设置为application / json,req.body是一个空对象

    {}
    

    当我将标题设置为application / x-www-form-urlencoded时,req.body显示

    { '{"jobid":"8746541","name":"asdfasdfasdfasdf","jobType":"LS","location":"asdfa"}':''}
    

    提交 XHR

    邮差Success

4 个答案:

答案 0 :(得分:1)

<强>解决方案

向app.js添加了行app.use(bodyParser.json());。从本质上讲,这告诉应用程序应该本机地理解JSON。现在,在应用程序中提交表单会导致将新记录添加到mongodb。

答案 1 :(得分:0)

在文件jobs.service中,您将Header设置为

'Content-Type':'application/json'

在文件index.js中处理正文请求

app.use(bodyParser.urlencoded({extended: false}));

所以你可以做两个解决方案。

1。)更改jobs.service

'Content-Type': 'application/x-www-form-urlencoded'

2。)或者更改index.js

app.use(bodyParser.json();

答案 2 :(得分:0)

在app.js中添加以下中间件...

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

有关更多信息,请访问此网站:link

答案 3 :(得分:0)

1。在前端级别:- 使用反应驱动形式时 通过前端类文件绑定 对象为getRawValue()。

1.1从前端到后端集成
例如我们确定的服务 调用时,我们必须传递方法 保存时绑定的对象包括 标头,好像是post方法。

  1. 通过需要bodyparser添加中间件。将use用作bodyparser.json。

  2. 导航到邮递员中的特定路线,然后首先检查新数据并将其发布。

  3. 现在与前端对象绑定。

  4. 传递给post rest API方法的是前端侧的对象。

大结局?