使用 Mongoose 和 GraphQL 保存实体后数据为空

Posted

技术标签:

【中文标题】使用 Mongoose 和 GraphQL 保存实体后数据为空【英文标题】:Data null after saving entity with Moongose and GraphQL 【发布时间】:2018-04-15 17:45:30 【问题描述】:

当使用 mongoose 和 graphql 保存实体时,会发生以下情况:

第一种保存方法:

create(budgetProps)
   const budget = new Budget(budgetProps);
   return budget.save();

结果如下:


  "data": 
    "addBudget": 
      "_id": "59fbdefaa7b0a81180dd2c9c",
      "tiempoAproximado": 2245.5,
      "User": 
        "name": null,
        "organization": null
      ,
      "Vehicle": 
        "name": null,
        "type": null
      
    
  

使用这种方法:

create(budgetProps)
  const budget = new Budget(budgetProps);
  return budget.save().then((res)=>
           Budget.findById(res._id)
              .populate('User')
              .populate('Vehicle')
              .exec((err, newBudget)=> 
                 return newBudget;
              );
        );
  ,

我得到以下信息:


  "data": 
    "addBudget": null
  

这是架构:

 const typeDefs = `
   scalar Date

   input UserInput 
      _id: ID,
      name: String,
      organization: String,
      phones: [String],
      emails: [String],
      type: String,
      password: String,
      percentaje: String
   

   input VehicleDescriptionInput 
      es: String,
      en: String
   

   input VehicleInput
      _id: ID,
      name: String,
      passengers: Int,
      largeBags: Int,
      smallBags: Int,
      doors: Int,
      type: String,
      status: Boolean,
      imagesUrls: [String],
      description: VehicleDescriptionInput
   

   input FinalTotalCostInput 
      es: String,
      en: String   
   

   input BudgetTotalCostInput 
      es: String,
      en: String
   

   input BudgetInput 
      finalTotalCost: FinalTotalCostInput,
      budgetTotalCost: BudgetTotalCostInput,
      destinoInicial: String,
      destinoFinal: String,
      tiempoAproximado: Float,
      distancia: Float,
      tollCost: Float,
      tolls: [String],
      budgetDate: Date,
      aprove: Boolean,
      User: UserInput,
      Vehicle: VehicleInput
   

   type Mutation 
      addBudget(data: BudgetInput): Budget
   
`;

这里是解析器:

Mutation: 
  addBudget: (_, data) =>
    return BudgetController.create(data);  
  
,

最后是带有变量的突变:

mutation addBudget($budget: BudgetInput) 
  addBudget(data: $budget) 
    _id
    User
      name
      organization
    
    Vehicle
      name
      type
    
  



  "budget": 
    "finalTotalCost": 
      "es": "100 peso",
      "en": "10 dolars"
    ,
    "budgetTotalCost": 
      "es": "80 peso",
      "en": "8 dolars"
    ,
    "destinoInicial": "Queretaro",
    "destinoFinal": "Sonora",
    "tiempoAproximado": 2245.5,
    "distancia": 100.565,
    "tollCost": 20.5,
    "tolls": [
      "GDL",
      "Marina",
      "Culap",
      "Malageña"
    ],
    "budgetDate": "2017/07/21",
    "aprove": false,
    "User": 
      "_id": "59fbcc42aa82460924e5fbad"
    ,
    "Vehicle": 
      "_id": "59fbcbe4aa82460924e5fbac"
    
  

实体已正确存储在数据库中,当 Console.log 填充的搜索结果正确时,我不明白发生了什么。

您可以在以下链接中找到整个应用程序:GitHub Repo

【问题讨论】:

【参考方案1】:

您正在混合 Promise 和回调。 exec() 将返回一个 Promise,但前提是没有任何参数传递给它。此外,您需要返回 exec() 返回的 Promise。

return budget.save().then((res) => 
  return Budget.findById(res._id) // missing return here
    .populate('User')
    .populate('Vehicle')
    .exec() // don't need anything else
)

你可以再清理一下:

return budget.save()
  .then(res => Budget.findById(res._id)
    .populate('User')
    .populate('Vehicle')
    .exec())

如果您需要在将findById返回的结果转给客户端之前进行转换:

return budget.save()
  .then(res => Budget.findById(res._id)
    .populate('User')
    .populate('Vehicle')
    .exec())
  .then(res => 
    res.foo = 'Foo'
    return res
  )

【讨论】:

以上是关于使用 Mongoose 和 GraphQL 保存实体后数据为空的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 graphql 和 mongoose 进行突变

如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用

如何将 Mongoose 与 GraphQL 和 DataLoader 一起使用?

在 Mongoose 和 GraphQL 中解决关系

使用 Mongoose 和 graphql-yoga 实现分页

GraphQL、Relay 和 Mongodb (mongoose) 如何获取数组