Query Fragments with Conditions in GraphQL
Tags: javascript, webdev, react, frontend
Published: 2023-07-21 11:46:57


![Graphql + Apollo + React](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7d2p34xz8574ks1kv87q.png)

OK let’s dive in real quick!

**GraphQL** is a query language and runtime that enables efficient data retrieval and manipulation from APIs. It allows clients to request specific data they need, reducing over-fetching and under-fetching issues commonly found in REST APIs. Its key benefits include increased flexibility, reduced network traffic, and improved developer productivity.

Now think of **fragments** as reusable units of fields used on the client side that can be defined and included in multiple queries. They allow you to define a set of fields once and use them in multiple places, making your queries more modular and concise.

Writing fragments is a good way to enhance code organization, reduce duplication, and make it easier to maintain and update queries as your schema evolves. They are particularly useful when you have common fields that are shared across different queries or when you want to abstract complex field selections into smaller, reusable components.

Let’s take a look at this example

```GraphQL
#First we define a fragment for a user
fragment UserFragment on User {
  id
  name
  email
  age
}

# A query using the defined fragment
# We use ...UserFragment to include within the user query
query GetUser {
  user(id: 123) {
    ...UserFragment
  }
}

# Another query using the same fragment
# We use ...UserFragment to include within the users query
query GetUsers {
  users {
    ...UserFragment
  }
}
```
OK with that being said let’s look at how we can query a fragment based on certain conditions from parent.

To query fragments based on certain conditions from a parent, you can use conditional directives or arguments in GraphQL. The specific implementation may vary depending on the GraphQL server or library you are using.

**Let’s see how we can accomplish this using Apollo Client.**

Let’s try to query a user’s profile and return all the fields. But we will conditionally include the user’s private posts or maybe liked posts based on the user Id, so we check if the post owner’s id is equal to the user Id. This can be a useful feature in a social media app.

OK let’s dive in!

![credit: https://gifer.com/en/PDE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98ad5g9ygotz1ymqbwv6.gif)

**Here are the steps**

First, we define the fragment for the user’s post, let’s call it **UserLikedPostsFragment**.

```JS
const userLikedPostsFragment = gql`
  fragment UserLikedPostsFragment on User {
    likedPosts {
      id
      content
    }
  }
`;
```
The **userLikedPostsFragment** specifies the field for the user’s posts, it includes the **id** and the **content** fields for each post.

We then determine if the user is the owner of the post by comparing the user ID and the post owner’s ID. If they match, we set **includeLikedPosts** to true; otherwise, we set it to false

```JS
// Assuming we have the user's ID
const userId = 'bldo123';

// Assuming we have post owner id
const postOwnerId = '456jsksi';

// Check if the user ID matches the post's owner ID
const isPostOwner = (userId === postOwnerId);

// Determine if we should include the user's liked posts in the query
const includeLikedPosts = isPostOwner;
```
Then, we create a **GET_USER** query that accepts the userId variable and an additional **includeLikedPosts** variable we just created. Inside the query, we conditionally include the **UserLikedPostsFragment** using the spread syntax (...) and the **@include** directive. The **@include** directive controls whether the fragment is included based on the value of **includeLikedPosts**

```JS
const GET_USER = gql`
  query GetUser($userId: ID!) {
    user(id: $userId) {
      id
      name
      email
      ...UserLikedPostsFragment @include(if: $includeLikedPosts)
    }
  }
`;
```
learn more about directives in Apollo-Client [here](https://www.apollographql.com/docs/react/data/directives/)

Then we can go on to execute our query

```JS
client.query({
  query: GET_USER,
  variables: {
    userId,
    includeLikedPosts,
  },
}).then((result) => {
  // Handle query result anyhow you wish
  console.log(result.data.user);
});
```

Notice the **$includeLikedPosts** variable is passed as a query variable when executing the query. Its value is determined based on the logic in the code (in this case, whether the user is the owner of the post).

By passing the variables (userId and includeLikedPosts) and the query to **client.query**, we can execute the query and handle the results accordingly.

So the LikedPosts will be returned if the condition is met that’s is if

```
userId === postOwnerId
```
Here’s the code snippet demonstrating how you can conditionally include the user’s posts based on the user ID using fragments in Apollo Client:

```JS
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
 uri: 'https://your-graphql-api-endpoint',
 cache: new InMemoryCache(),
});


const userLikedPostsFragment = gql`
 fragment UserLikedPostsFragment on User {
 likedPosts {
   id
   content
 }
 }
`;

//Assuming we have the user's ID
const userId = 'bldo123';

// Assuming the user owns the post
const postOwnerId = '456jsksi';

//Check if the user ID matches the post's owner ID
const isPostOwner = (userId === postOwnerId);

// Determine if we should include the user's liked posts in the query
const includeLikedPosts = isPostOwner;
client.query({
 query: GET_USER,
 variables: {
 userId,
 includeLikedPosts,
 },
}).then((result) => {
 // Handle query result
 console.log(result.data.user);
});

```

Hope you enjoyed the post. If you did hit the ❤️ button, share and follow for more amazing content. Bye 👋