Apollo GraphQL - Как использовать тему RxJS в качестве переменной с клиентом Apollo? - PullRequest
0 голосов
/ 09 июля 2019

Мой поиск с опережением по типу отлично работал с REST, но я перехожу на GraphQL, у которого есть свои проблемы.

Когда пользователь вводит фамилию в поле формы, предлагаемые результаты отображаются в таблице данных ниже. Каждое письмо обрабатывается субъектом RxJS.

var searchTerm $ - это тип наблюдаемого RXJS, который называется Предмет, привязанный к HTML. Следующее вызывается из ловушки жизненного цикла OnViewInit в приложении Angular. Поиск осуществляется по столбцу базы данных last_name.

Однако это приводит к ошибке Bad Request 400, так как представление загружается и поиск не работает. Я думал, может быть, это требует подписки, но все, что я нахожу на них, об использовании веб-сокетов для подключения к удаленному 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;
  }

Edit:

Ошибка с панели «Сеть» в инструментах разработчика. Консольное сообщение бесполезно.

{"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 голосов
/ 18 июля 2019

Во-первых, большое спасибо замечательному Дэниелу Рардену за его помощь по различным вопросам, так как я и многие другие на SO изучают GraphQL! У него терпение!

Как отметил Даниэль в комментариях, у меня была простая ошибка. Я укажу это в приведенном ниже коде. Однако большая проблема заключалась в попытке использовать наблюдаемый, предметный или подобный метод в качестве переменной. Даже если субъект RxJS испускает строку, GraphQL будет ненавидеть попытки использовать большой объект в качестве переменной. Поэтому мне пришлось использовать небольшое реактивное программирование, чтобы решить эту проблему.

Настройка наблюдаемого:

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'];
        },
      );
}
...