【问题标题】:Building GraphQL Resolver to Return List of Strings -- Receiving [object Object] Instead of Strings构建 GraphQL 解析器以返回字符串列表——接收 [object Object] 而不是字符串
【发布时间】:2019-03-31 18:10:30
【问题描述】:

我正在开发一个使用 GraphQL 查询 OrientDB 图形数据库的 Web 应用程序。它使用Apollo Server 来解析传入的 GraphQL 查询。

我想构建一个查询,该查询将简单地将每个“主题”对象的“名称”字段作为字符串列表返回。例如:

{
  "data": {
    "allTopicNames": [
      "Topic 1",
      "Topic 2",
      "Topic 3",
      "Topic 4"
    ]
  }
}

为此,我创建了一个类型定义

// Imports: GraphQL
import { gql } from 'apollo-server-express';

// GraphQL: TypeDefs
const TYPEDEFS = gql`
type Query {
    allTopics: [Topic]
    topic(name: String): [Topic]
    allTopicNames: [String] //This is the new Type Definition -- we want a list of Strings
  }
type Topic {
    name: String
}
`;

// Exports
export default TYPEDEFS;

以及相关的解析器

//Connect to OrientDB
var OrientJs = require('orientjs');

var server = OrientJs({
    host: "localhost",
    port: "2424",
    username: "root",
    password: "root"
});

var db = server.use({
    name: 'database',
    username: 'root',
    password: 'root'
});

// GraphQL: Resolvers
const RESOLVERS = {
    Query: {
        allTopics: () => {
            return db.query('SELECT FROM Topic ORDER BY name');
        },
        allTopicNames: () => {
            return db.query('SELECT name FROM Topic ORDER BY name'); //This is the new resolver
        },
        topic: (obj, args) => {
            return db.query('SELECT FROM Topic WHERE name=\'' + args.name + '\' LIMIT 1');
        }
    }
};

// Exports
export default RESOLVERS;

但是,当我尝试实现上述类型定义和解析器时,我收到一个字符串列表,这些字符串都是“[object Object]”而不是实际的字符串:

{
  "data": {
    "allTopicNames": [
      "[object Object]",
      "[object Object]",
      "[object Object]",
      "[object Object]"
    ]
  }
}

我尝试向解析器添加一些代码,该代码将遍历每个对象并创建一个适当的字符串列表以返回:

// GraphQL: Resolvers
const RESOLVERS = {
    Query: {
        allTopics: () => {
            return db.query('SELECT FROM Topic ORDER BY name');
        },
        allTopicNames: () => {
            let the_list_of_records = db.query('SELECT name FROM Topic ORDER BY name').then(res => { 
                let the_list_of_names = []; //We'll return a List of Strings using this
                for(var i = 0; i < res.length; i++){
                    the_list_of_names.push(res[i]['name']);
                }
                console.log(the_list_of_names);
                return the_list_of_names;
            });
        },
        topic: (obj, args) => {
            return db.query('SELECT FROM Topic WHERE name=\'' + args.name + '\' LIMIT 1');
        }
    }
};

但这不起作用,导致返回一个空值:

{
  "data": {
    "allTopicNames": null
  }
}

坦率地说,我很困惑为什么我不能通过这个解析器获得一个简单的字符串列表来填充。也许我遗漏了一些明显的东西——非常感谢任何见解!

【问题讨论】:

    标签: graphql orientdb apollo apollo-server


    【解决方案1】:

    您的初始方法没有按预期工作,因为您返回了一个对象数组。您的第二次尝试返回 null 因为您没有在解析器中返回任何内容。您的解析器应始终返回一个值或将解析为该值的 Promise,否则该字段的已解析值将始终为空。

    the_list_of_records 的值将是一个 Promise,因此您只需返回它就足够了。但是我们可以像这样使用map 使这段代码更易于阅读:

    allTopicNames: () => {
      return db.query('SELECT name FROM Topic ORDER BY name').then(res => {
        return res.map(topic => topic.name)
      })
    }
    
    // using async/await
    allTopicNames: async () => {
      await topics = await db.query('SELECT name FROM Topic ORDER BY name')
      return topics.map(topic => topic.name)
    }
    

    【讨论】:

    • 非常感谢您的解释。我想我明白我的问题是什么。我会尝试实现它,看看它是否有效。
    • 抱歉耽搁了。我今天能够实施您建议的修复程序,它现在可以按需要工作。谢谢!
    猜你喜欢
    • 2011-07-27
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 2014-07-11
    • 2020-08-30
    • 2022-11-03
    • 2021-07-12
    • 2021-11-15
    相关资源
    最近更新 更多