【问题标题】:fetch POST returns only _id object in Express API server React FrontEndfetch POST 在 Express API 服务器 React FrontEnd 中仅返回 _id 对象
【发布时间】:2018-04-22 15:37:43
【问题描述】:

我正在尝试制作一个 React-Node.js 应用程序以供练习。我在发送 POST 请求时遇到问题。当我在 App.js 中获取 POST 请求时,它只返回 id。我预计它会返回 3 个以上的值。

当前对象

{ _id: 5a046d52bb5d37063b3c8b21 }

理想对象

{_id: "59e9fed60fe8bf0d7fd4ac6e", name: "recipe1", ingredients: "apple", descriptions: "cut an apple"}

我应该如何正确地向 req.body 添加值?我提到了这个解决方案Post an object with fetch using react js and express API server,但它不适用于我的应用程序。

index.js (node.js)

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();

 // Serve static files from the React app
app.use(express.static(path.join(__dirname, 'client/build')));

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

var db

const MongoClient = require('mongodb').MongoClient

MongoClient.connect
('mongodb://Recipe:recipebox@ds125914.mlab.com:25914/ayumi', (err, database) => {
 if (err) return console.log(err)
 db = database
 app.listen(8080, () => {
    console.log('listening on 8080')
 })
 })

 app.get('/api', (req,res)=> {
     db.collection('recipe').find().toArray((err, results) => {
     if(err) return console.log("no recipe");
         res.json(results);
     })
 })

 app.post('/recipe', (req,res)=>{
     db.collection('recipe').save(req.body, (err, result) => {
     if(err) return console.log(err);
          console.log(req.body)
    console.log('save to database');
    res.redirect('/');
})
})

App.js(反应)

class App extends Component {
constructor(props){
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
}

handleSubmit(e){
  e.preventDefault();
  fetch('/recipe', {
       method: 'POST',
       body: JSON.stringify({
           name: this.refs.name.value,
           ingredients: this.refs.ingredients.value,
           descriptions: this.refs.descriptions.value
       }),
       headers: {"Content-Type" : "application/json"}
       })
  .then((res)=> {
      return res.json()
  })
  .then((body)=>{
      console.log("body" + body)
      console.log("result" + this.refs.name.value)
  })
}

render() {

return (
  <div className="App">
  <h1>Recipe List</h1>
  <form onSubmit={this.handleSubmit}>
  <input type="text" placeholder="name" ref="name" />
  <input type="text" placeholder="ingredients" ref="ingredients" />
  <input type="text" placeholder="descriptions" ref="descriptions" />
  <input type="submit"/>
  </form>
  </div>
  )
}

}

导出默认应用;

【问题讨论】:

  • 我很惊讶你得到 anything 考虑到 POST 方法服务器端只是以重定向结束并且从不使用 result 值(可能包含你新创建的数据对象)。你看到值被写入数据库吗?
  • 未添加值。每个对象只包含像 {"_id":"5a0472c56f37cb06a4c8f54c"}] 这样的 id
  • 但是每次添加配方时,recipe 集合中都会有一个新条目,其中只有 _id 字段集,对吗?
  • console.log(req.body) 中的 app.post 显示什么?
  • 显示listening on 8080 { _id: 5a0472c56f37cb06a4c8f54c } save to database

标签: node.js reactjs express fetch


【解决方案1】:

服务器端更改:

app.post('/recipe', (req, res) => {
  // log the body of the request, to make sure data is properly passed
  console.log(req.body);
  // use mongodb's insertOne instead of the deprecated save
  db.collection('recipe').insertOne(req.body, (err, result) => {
    if (err) return console.log(err);
    // log the result of db insertion
    console.log(result);
    console.log('saved to database');
    // send the freshly saved record back to the front-end
    res.json(result);
  });
});

前端变化:

class App extends Component {
  constructor(props){
    super(props);
    // add state to hold recipe returned from POST call
    this.state = {
      recipe: null,
      name: '',
      ingredients: '',
      descriptions: ''
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(e) {
    e.preventDefault();
    const { name, ingredients, descriptions } = this.state;
    fetch('/recipe', {
      method: 'POST',
      body: JSON.stringify({
        name,
        ingredients,
        descriptions
      }),
      headers: {"Content-Type" : "application/json"}
    })
    // when call completes, it should return the newly created recipe object
    // as it was saved in the DB - just store it into state
    .then((recipe)=> {
      this.setState({recipe});
    });
    // TODO: handle error case
  }

  render() {
    // added a paragraph tag to display the ID of the freshly created recipe
    // it's only displayed if recipe is not null or undefined
    // further changes: turning inputs into controlled inputs
    const { name, ingredients, descriptions } = this.state;
    return (
      <div className="App">
        <h1>Recipe List</h1>
        <form onSubmit={this.handleSubmit}>
          <input
            value={name}
            type="text"
            onChange={e => this.setState({ name: e.target.value })}
            placeholder="name" />
          <input
            value={ingredients}
            type="text"
            onChange={e => this.setState({ ingredients: e.target.value })}                
            placeholder="ingredients" />
          <input
            value={descriptions}
            type="text"
            onChange={e => this.setState({ descriptions: e.target.value })}
            placeholder="descriptions" />
          <input type="submit"/>
          { recipe &&
            <p>Saved ID: {this.state.recipe._id}</p>
          }
        </form>
      </div>
    );
  }
}

export default App;

进一步更改:将所有三个文本输入变为受控输入(所有 3 个字段的值都在状态中进行跟踪,并在提交表单时传递给 fetch)。

【讨论】:

  • 非常感谢您的回答!我试过了,但是除了_id之外没有添加任何数据。终端中的结果:CommandResult { result: { n: 1, opTime: { ts: [Object], t: 2 }, electionId: 7fffffff0000000000000002, ok: 1 }, connection: Connection { domain: null, _events: { error: [Object], close: [Object], timeout: [Object], parseError: [Object] }, .....
  • @aaayumi console.log(req.body)的输出是什么(app.post('/recipe', ...)的开头)?
  • @aaayumi 那么这就是你的问题所在,不知何故你传递的是空/无数据,这就解释了为什么数据库中的对象除了创建的_id 之外没有数据由数据库自动生成。
  • @aaayumi 在客户端的handleSubmit 方法中,尝试记录您尝试传递的三个值中的一个(或全部),即console.log(this.refs.name.value)。将该日志放在fetch 调用之前。
  • @aaayumi 我已经更新了我的答案,将所有 3 个输入都转换为受控输入,因为我怀疑问题可能出在使用 refs 上。仅在前端进行了更改。
猜你喜欢
  • 2020-09-17
  • 2017-12-30
  • 2020-09-09
  • 2019-07-03
  • 1970-01-01
  • 2019-08-08
  • 2019-10-04
  • 2019-03-18
  • 1970-01-01
相关资源
最近更新 更多