0

I use Angular 13 and apollo-angular 3.0.0. I have the codes to make GraphQL query:

const GET_TODOS = gql`
  query GetTodos() {
    todos() {
      id
      title
      brief
      body
      tags
      created_at
      updated_at
      author {
        id
        nickname
        avatar
        created_at
        updated_at
      }
    }
  }`;

const GET_TODO_BY_ID = gql`
  query GetTodosById($id: String!) {
    todos(id: $id) {
      id
      title
      brief
      body
      tags
      created_at
      updated_at
      author {
        id
        nickname
        avatar
        created_at
        updated_at
      }
    }
  }`;


getTodos(): Observable<any> {
  return this.apollo.watchQuery({
    query: GET_TODOS,
    variables: {},
  }).valueChanges;
}

getTodoByID(id: string): Observable<any> {
  return this.apollo.watchQuery({
    query: GET_TODO_BY_ID,
    variables: { id },
  }).valueChanges;
}

There are duplicated codes in both GET_TODOS and GET_TODO_BY_ID object.
Is there a way to reduce the duplicated codes so that I can define the struct of Todo and Author once and reuse the struct to make GET_TODOS or GET_TODO_BY_ID query.

I know Fragment in GraphQL, but I don't know how can I write the Fragment in angular. Someone can help me?

Rocketk
  • 11
  • 1

1 Answers1

0

To use fragment with apollo-angular when querying the graphql server

create a variable like this

POST_FIELDS = gql`
    fragment POST_FIELDS on Post {
      _id
      title
      content
      creator {
        _id
        name
        email
      }
      imageUrl
      updatedAt
    }
  `;

The explanation for above query is as follow -

  • POST_FIELDS - Name of fragment to be used
  • Post - Defined schema name on your graphql server (Not on your frontend)
  • Rest of the inner fields of Post is the schema of post

Now use the fragment in your gql query like this

this._apolloClient.watchQuery<any>({
      query: gql`
        query FetchPosts($page: Int = 1) { // FetchPosts is the operation name
          posts(page: $page) { // posts is the resolver to execute on server
            posts { // Required response
              ...POST_FIELDS // Used the defined fragment
            }
            totalPosts // // Required response
          }
        }
        ${this.POST_FIELDS} // Injected the above defined fragment
      `,
      variables: {
        page: 1,
      },
      context: {
        headers: new HttpHeaders().set("Authorization", this.token), // Passed additional custom header along with the global headers
      },
    }).valueChanges.subscribe({
      next: (result: any) => {
        this.posts = result?.data?.posts.posts;
        this.loading = result.loading;
        this.error = result.error;
        console.log('Logging Fetch Posts Query----', this.posts, this.loading, this.error);
      }
    });

Note: Do remove the comments from gql template literal query while using the exact code as explained above.

Hope this help you or somebody else.

Happy Coding! Thanks.

Aman Kumar Gupta
  • 2,640
  • 20
  • 18