【问题标题】:Angular Apollo Set watchQuery Results to a Usable VariableAngular Apollo 将 watchQuery 结果设置为可用变量
【发布时间】:2020-12-25 10:38:39
【问题描述】:

Angular/Apollo/TS 的新手,这让我发疯了,因此非常感谢任何帮助。

我正在使用 Angular 10、Apollo 和 GraphQL API 设置一个小型应用程序。我最近在 Vue 中构建了相同的东西,并认为重新创建项目将是学习一些 Angular 的好方法。

我与 API 的连接正常,我的查询也是如此,但我不知道如何将结果映射到数组,以便我可以在我的组件中访问它们。在订阅中使用 console.log 显示返回了正确的数据。 'this' 查询之外的 console.log 显示查询结果,但是它们永远不会保存/映射到它们应该设置的变量。

这是我的服务的代码:

import { Injectable } from '@angular/core';

import { Apollo } from 'apollo-angular';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import gql from 'graphql-tag';

const USER_SEARCH = gql`
  query getUsers {
    search(query: "moose", type: USER, first: 10) {
       nodes {
         ... on User {
           login
           email
           location
           name
         }
       }
       pageInfo {
         hasNextPage
         hasPreviousPage
         startCursor
         endCursor
       }
       userCount
     }
  }`;

export class UserService {
  loading: boolean = true;
  users: [];

  constructor(private apollo: Apollo) { }

  getUsers(): any {
    this.apollo.watchQuery<any>({
      query: USER_SEARCH
    })
      .valueChanges
        .subscribe(({ data, loading }) => {
         this.loading = loading;
         this.users = data.search;
        });
        console.log(this);

    return this.users;
  }
}

我可以从我的组件中调用 getUsers() 函数,'this' 列出了服务,其中的 'users' 列出了我的查询结果。但是,服务或组件中 this.users 的 console.log 返回 undefined。

我已经尝试了我能找到的所有类型的示例,包括来自 apollo 文档的查询示例,以及来自 hasura.io 的将 apollo 与 angular 结合使用的示例。尝试使用管道和映射,pluck,只是 valueChanges,一些不同的订阅,在函数内部设置一个变量来分配数据值,将查询设置为变量,在组件中的 ngOnInit 中设置查询,以及其他一些事情我确定我忘记了。似乎没有任何效果。我研究过在设置值之前使用回调来等待查询返回,但我的理解是我不应该做这样的事情。我确定这是我缺少的东西,或者我不知道 Apollo 或 Angular 的东西,但我只是不确定我缺少的是什么。

有什么想法吗?

【问题讨论】:

标签: javascript angular typescript graphql apollo


【解决方案1】:
this.getUsers = this.getUsers.bind(this);

在构造函数中?

【讨论】:

  • 感谢您的建议!这不是直接开箱即用的,但绑定范围至少给了我一些新的工作。欣赏!
【解决方案2】:

使用setTimeout 不是一个理想的解决方案,您可以直接在订阅回调函数中更新您的组件变量,并在您的模板中做任何您想做的事情。看我的例子

getItems() {
    this.apollo
      .watchQuery({
        query: this.getItemsQuery,
      })
      .valueChanges.subscribe((result: any) => {
        this.items = result?.data?.items;
      });
  }

在模板中

<mat-option *ngFor="let item of items" [value]="item.price">
    {{ item.name }}
</mat-option>
            
 
     
            

【讨论】:

    【解决方案3】:

    也许不是理想的解决方案,所以我仍然愿意尝试其他事情,但我能够通过在服务中使用带有计时器的承诺,然后在组件中使用异步等待来获取组件中设置的值.

    服务

      getUsers(): any {
        return  new Promise((resolve, reject) => {
          let me = this;
          this.apollo.watchQuery<any>({
            query: USER_SEARCH
          })
            .valueChanges
              .subscribe(({ data, loading }) => {
               this.loading = loading;
               this.users = data.search;
             });
    
          setTimeout( function() {
            if(me.users !== 'undefined'){
              resolve(me.users)
            }
          }, 1000)
        })
      }
    

    组件

      async getUsers(): Promise<any> {
          this.users = await this.userService.getUsers();
          console.log(this.users);
      }
    

    这允许从服务中设置 this.users。据我所知,当 Angular 开始设置值时,Apollo 仍在运行查询,导致该值最初显示为未定义,但我的服务具有来自控制台中查询的值。不确定 Apollo 或 Angular 是否有更好的方法来解决此问题,但如果有,我很想听听。

    谢谢!

    【讨论】:

      猜你喜欢
      • 2020-01-25
      • 2020-08-03
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 2013-09-27
      • 2019-07-09
      • 1970-01-01
      相关资源
      最近更新 更多