Apollo GraphQL-如何在Apollo Client中将RxJS Observable用作变量?

时间:2019-07-09 18:49:38

标签: graphql apollo

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

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

var searchTerm $是一个可观察到的RXJS,并绑定到HTML。从Angular应用程序的OnViewInit生命周期挂钩中调用以下内容。搜索是通过数据库列last_name进行的。

但是,这会导致Bad Request 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行左右的属性和方法。

1 个答案:

答案 0 :(得分:0)

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

如果您阅读上面的评论,我会提到我正在使用RsJS主题。我将其更改为可观察的,因为我不需要多个观察者。

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

设置可观察对象:

public searchTerm$ = new Observable<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'];
        },
      );
}