Apollo GraphQL - 如何将 RxJS 主题用作 Apollo 客户端的变量?

Posted

技术标签:

【中文标题】Apollo GraphQL - 如何将 RxJS 主题用作 Apollo 客户端的变量?【英文标题】:Apollo GraphQL - How do I use an RxJS Subject as a variable with Apollo Client? 【发布时间】:2019-11-19 09:17:58 【问题描述】:

我的预输入搜索在 REST 上运行良好,但我正在转换为 GraphQL,这有其挑战。

当用户在表单字段中输入姓氏时,建议的结果会显示在下面的数据表中。每个字母都由 RxJS 主题处理。

var searchTerm$ 是一种 RXJS 可观察对象,称为 Subject 绑定到 html。以下是从 Angular 应用程序中的 OnViewInit 生命周期挂钩调用的。通过数据库列 last_name 进行搜索。

但是,由于视图加载和搜索不起作用,这会导致错误请求 400 错误。我想这可能需要订阅,但我在上面找到的所有内容都是关于使用 Web 套接字连接到远程 URL 和服务器。我从这里去哪里?

我将 Angular Apollo 客户端与 Apollo Express 一起使用,但我对任何 JS 解决方案都很满意,并尝试从那里解决问题。服务器端是 Nestjs,它只是封装了 Apollo Server。

const lastNameSearch = gql `
        query ($input: String!) 
          lastNameSearch(input: $input) 
            first_name
            last_name
            user_name
            pitch
            main_skill_title
            skills_comments
            member_status
          
    `;
this.apollo
      .watchQuery(
        query: lastNameSearch,
        variables: 
          last_name: searchTerm$, // Trying to use the observable here.
        ,
      )
      .valueChanges
      .subscribe(result => 
        console.log('data in lastNameSearch: ', result);
      ),

服务器上的架构:

lastNameSearch(input: String!): [Member]

解析器:

@Query()
  async lastNameSearch(@Args('input') input: String) 
    const response = await this.membersService.lastNameSearch(input);
    return await response;
  

编辑:

来自开发工具中网络面板的错误。控制台消息毫无价值。

"errors":["message":"Variable \"$input\" of required type \"String!\" was not provided.","locations":["line":1,"column":8],"extensions":"code":"INTERNAL_SERVER_ERROR","exception":"stacktrace":["GraphQLError: Variable \"$input\" of required type \"String!\" was not provided.","    at getVariableValues

这会继续显示应用程序中的属性和方法,大约有 300 行。

【问题讨论】:

错误请求通常意味着查询中的语法或验证错误。检查来自服务器的完整响应以获取详细信息,或者如果您需要帮助解决问题,请使用查询和完整错误更新您的问题 丹尼尔,我不会忽视你的评论!我开始得到你要的东西,我的 Mac 被锁了。恢复并不顺利,然后我的完整堆栈需要两天的升级依赖地狱。一切恢复正常后回复您。 OK Daniel,我在帖子中添加了似乎是错误消息中最重要的部分。我不知道如何从中找出问题。 不要从控制台获取错误,而是打开开发者控制台的网络选项卡并查看服务器的实际响应。这应该包含更详细的消息,如果是语法错误,通常会详细到行号和列。 糟糕,抱歉,累了。我修正了我的问题中的一个错字并发布了错误。 “未提供”是问题,但我不知道如何提供。假设我在输入表单中输入“p”。我的 searchTerm$ var 绑定到表单,并且应该提供 var。但是,表单在呈现时由于 GraphQL 而崩溃。我在构造函数中有 Angular 代码,因为它最适合 REST。令人困惑。 【参考方案1】:

首先,非常感谢令人惊叹的 Daniel Rarden 在我和其他许多人学习 GraphQL 时在各种问题上提供的帮助!他有耐心!

正如丹尼尔在 cmets 中指出的那样,我犯了一个简单的错误。我将在下面的注释代码中指出它。但是,最大的问题是尝试使用可观察的、主题或类似的方法作为变量。即使 RxJS 主题发出字符串,GraphQL 也会讨厌尝试将大对象用作 var。所以我不得不使用一点反应式编程来解决这个问题。

设置可观察对象:

public searchTerm$ = new Subject<string>(); // Binds to the html text box element.

其次,让我们在生命周期钩子中进行设置,在该钩子中订阅可观察对象,以便在将字母输入输入框时一次发出一个字母。

ngAfterViewInit() 

      let nextLetter: string;

      // -------- For Last Name Incremental Query --------- //
      this.searchTerm$.subscribe(result => 
        nextLetter = result;  // Setup a normal variable.
        this.queryLastName(nextLetter); // Call the GraphQL query below.
      );

最后一步,我们有 GraphQL 查询并使用返回的数据对象。这非常适合在表单中输入“p”并从数据库中返回所有以“p”或“P”开头的姓氏。键入“r”,结果会缩小到以“pr”开头的姓氏,依此类推。

private queryLastName(nextLetter) 
    const lastNameSearch = gql`
        query ($input: String!) 
            lastNameSearch(input: $input) 
                first_name
                last_name
                user_name
                pitch
                main_skill_title
                skills_comments
                member_status
            
        `;

    this.apollo
      .watchQuery(
        query: lastNameSearch,
        variables: 
          input: nextLetter, // Notice I had used last_name here instead of input.
        ,
      )
      .valueChanges
      .subscribe(result => 
          // Put the data into some UI in your app, in this case
          //    an Angular Material data table.
          // Notice how we get the data from the returning object.
          // The avoids the dreaded "null" error when the shape of the 
          //    returned data doesn't match the query. This put an array
          //    of objects into the UI.

          this.dataSource.data = result.data['lastNameSearch'];
        ,
      );

【讨论】:

以上是关于Apollo GraphQL - 如何将 RxJS 主题用作 Apollo 客户端的变量?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo/graphQL:如何将乐观 UI 用于嵌套反应组件的突变?

Apollo GraphQL技术栈概览:如何将所有的功能组合起来

如何将数据从反应组件传递到 Apollo graphql 查询?

如何将标头添加到 ionic 4 / Apollo GraphQL App

如何将对象数组粘贴到 GraphQL Apollo 缓存中?

Apollo GraphQL - 将 .graphql 模式导入为 typeDefs