How to Build Angular Search Functionality with GraphQL?
Published: 2023-03-27 12:46:11

In this tutorial, you will learn how to build a fullstack Angular application that uses GraphQL to fetch data from a server. The application we'll build together will display a list of blog posts fetched from a GraphQL API using Apollo Client, including search functionality. To create the GraphQL API, we will use StepZen, a GraphQL API platform that allows you to build and deploy a GraphQL API in minutes.

Do you prefer watching a video walkthrough instead? Check out the link below:

[![Watch a video walkthrough of Getting Started With GraphQL in Angular using StepZen](https://i.ytimg.com/vi/Cuh79sEvWqI/hqdefault.jpg)](https://youtu.be/Cuh79sEvWqI)

Introduction
------------

Google has developed Angular, an open-source web application framework based on TypeScript. The initial release of Angular from angular.js involved a complete rewrite, enabling the creation of large-scale, cross-platform applications.

Angular has gained a reputation for its exceptional developer tooling, which includes built-in features such as TypeScript support, routing, and a command-line interface. Additionally, Angular's component-based architecture, remarkable speed and performance, and other powerful features make it a popular choice among developers.

Prerequisites
-------------

To follow this tutorial, you will need the following:

*   [Node.js](https://nodejs.org/en/download/) installed on your machine
*   [Angular CLI](https://cli.angular.io/) installed on your machine (you can install it globally by running the following command using npm: `npm install -g @angular/cli`)
*   [StepZen CLI](https://stepzen.com/docs/quickstart) installed on your machine (you can install it globally by running the following command using npm: `npm install -g stepzen`)

> You can find the source code for this tutorial on [GitHub](https://github.com/stepzen-dev/examples/tree/main/with-angular).

Setting up a new Angular project
--------------------------------

To build an Angular application, we will use the Angular CLI. The Angular CLI is a command-line interface that allows you to create, build, and test Angular applications.

If you don't have the Angular CLI already on your machine, you can install it globally by running the following command using npm:

```bash
`npm install -g @angular/cli`

```

> Note: The Angular CLI requires a minimum Node.js version of either v14.20, v16.13, or v18.10. With the Angular CLI installed, we can now create a new Angular application by running the following command:

```bash
`ng new with-angular --directory ./with-angular`

```

This command will create a new Angular application named `with-angular`, and we specified the directory where the application will be created with the'-- directory' flag. The Angular CLI will create a new directory named `with-angular` if it doesn't exist and will create the application inside the directory.

After the Angular CLI has finished creating the application, we can now navigate to the application directory and start the development server by running the following commands:

```bash
cd with-angular
ng serve --open
```

The `ng serve` command will start the development server, and the `--open` flag will open the application in the default browser.

![The starter Angular application](https://stepzen.com/images/blog/starter-angular-application.png)

With the starter application running, we can now start building our application. But before we can start building the application, we need to create a GraphQL API that we can use to fetch data. In the next section, we'll create a GraphQL API using StepZen.

Creating a GraphQL API with StepZen
-----------------------------------

The Angular application we build in this blog post will fetch data from a GraphQL API. To create a GraphQL API, we will use StepZen, a GraphQL API platform that allows you to build and deploy a GraphQL API in minutes. One of the capabilities of StepZen is transforming REST APIs into GraphQL APIs, which will be demonstrated in this tutorial.

Before creating a GraphQL API, we need to create a StepZen account. You can create a free account by visiting the [StepZen website](https://stepzen.com/signup). And once you've created an account, you can install the StepZen CLI (if you haven't already) by running the following command:

```bash
`npm install -g stepzen`

```

With the StepZen CLI installed, we can now create a new StepZen project in the `with-angular` directory by running the following command:

```bash
mkdir stepzen
stepzen init --endpoint=api/with-angular
```

The blog posts we want to show in our application are fetched from the [DEV.to](https://dev.to/) API. More specifically, we will fetch the posts from the DEV.to API's `articles` endpoint: `https://dev.to/api/articles?username=gethackteam`. The `articles` endpoint returns a list of articles, and you could provide a different username to fetch articles from another user.

To create a GraphQL API that fetches data from the DEV.to API, we can use the `import` command from the StepZen CLI. This command will create a GraphQL schema for this REST API:

```bash
`stepzen import curl 'https://dev.to/api/articles?username=gethackteam' --name=posts --query-type=Posts --query-name=posts`

```

Which generates a new GraphQL schema in a directory named `posts`, which has a query called `posts` that returns a list of posts. The `--query-type` flag specifies the name of the type that the query will return, and the `--query-name` flag specifies the query's name.

From a different DEV.to endpoint, we want to retrieve a single post by its ID to retrieve a list of posts. To do this, we can use the `import` command again, but this time we'll use the `--query-type` and `--query-name` flags with different values to specify the name of the type and query:

```bash
`stepzen import curl 'https://dev.to/api/articles/1366695' --name=post --query-type=Post --query-name=post`

```

There might be some overlap between type names when importing multiple REST APIs using `stepzen import curl`. The StepZen CLI will notify you of this, and you can manually delete the duplicated types from the GraphQL schemas. For this project, we can delete the `User`, and `Organization` types from the file `post/index.graphql` as these were already specified in the schema for the first import.

To deploy the GraphQL API, we can run the following command:

```bash
`stepzen start`

```

This command will deploy the GraphQL API to the StepZen cloud. Once the GraphQL API is deployed, you explore the GraphQL API from the Explorer in the StepZen dashboard by visiting the following URL: [https://dashboard.stepzen.com/explorer?endpoint=api%2Fwith-angular%2F\_\_graphql](https://dashboard.stepzen.com/explorer?endpoint=api%2Fwith-angular%2F__graphql).

From the Explorer, you can run queries and mutations against the GraphQL API. For example, you can run the following query to retrieve a list of posts:

```graphql
query GetPosts {
  posts {
    id
    title
    description
  }
}
```

You can also search for articles from a specific user by changing the `username` parameter in the query, as shown in the screenshot below.

![The StepZen Explorer](https://stepzen.com/images/blog/angular-application-graphql-explorer.png)

With the GraphQL API deployed, we can now start building our Angular application. In the next section, we'll add Apollo Client to our Angular application.

Adding Apollo Client to our Angular application
-----------------------------------------------

Install Apollo Client for Angular

```bash
`ng add apollo-angular`

```

> We're using the Angular CLI to add the library `apollo-angular` rather than npm, as this will autogenerate some of the boilerplate code to set up Apollo Client. The Angular CLI will prompt you for the endpoint of your GraphQL API, which you can answer with the endpoint of your GraphQL API that you deployed in the previous step. The endpoint of your GraphQL API is printed in the terminal after running `stepzen start`, and will look something like this: `https://YOUR_USERNAME.stepzen.com/with-angular/__graphql`.

Once entering your GraphQL API endpoint and the GraphQL version (you can use the suggested one), the Angular CLI will generate the setup files for Apollo Client and reference it in the entry point of your application:

```bash
CREATE src/app/graphql.module.ts (713 bytes)
UPDATE package.json (1128 bytes)
UPDATE tsconfig.json (895 bytes)
UPDATE src/app/app.module.ts (462 bytes)
```

These steps complete the installation of Apollo Client but don't handle the data fetching part yet. The next section will add a new Angular component and fetch data from the GraphQL API.

Fetching data with Apollo Client
--------------------------------

The query we'll use to display the blog posts is the same one we created in the first part of this blog post. You need to create a new file called `graphql.operations.ts` in the `app` directory and add the following content:

```typescript
import { gql } from 'apollo-angular'

const GET_POSTS = gql`
    query GetPosts {
        posts {
        id
        title
        description
        }
    }
`

export { GET_POSTS }
```

And use the Angular CLI to generate the boilerplate files for a new component called `posts` in the `app` directory:

```bash
`ng generate component posts --module app`

```

The Angular CLI will create a new directory called `posts` with the files for the business logic (`*.ts`), styling (`*.css`), markup (`*.html`), and testing (`*.spec.ts`).

To add the logic to fetch the data from the GraphQL API, you can replace the code in `posts/posts.component.ts` with the following:

```typescript
import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { GET_POSTS } from '../graphql.operations';

@Component({
  selector: 'app-posts',
  templateUrl: './posts.component.html',
  styleUrls: ['./posts.component.css']
})

export class PostsComponent implements OnInit {
  posts: any[] = [];
  error: any;
  constructor(private apollo: Apollo) { }
  ngOnInit(): void {
    this.apollo.watchQuery({
      query: GET_POSTS
    }).valueChanges.subscribe(({ data, error }: any) => {
      this.posts = data.posts;
      this.error = error;
    }
    );
  }
}
```

But we also need to add the styling and markup to render the posts in the application. In `posts.component.html` and `posts.component.css`, let's add the following HTML and CSS:

Add the following HTML code in `posts.component.html`:

```html
<div class="main">
    <div *ngIf="error">
        <p>Error: {{ error }}</p>
    </div>
    <div class="posts-container" *ngIf="posts">
        <ul>
            <li *ngFor= "let post of posts">
                <div class="post">
                    <span class="post-title">{{ post.title }}</span>
                    <span class="post-description">{{ post.description }}</span>
                </div>
            </li>
        </ul>
    </div>
</div>
```

And the following CSS in `posts.component.css`:

```css
.main {
    margin-top: 60px;
}
.posts-container ul {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 10px;
}
.posts-container ul li {
    padding: 10px;
    border-bottom: 1px solid #e0e0e0;
}
.post {
    display: flex;
    flex-direction: column;
    padding: 10px;
}
.post-title {
    font-size: 18px;
    font-weight: bold;
    padding-bottom: 10px;
}
.post-description {
    font-size: 14px;
}
```

3.  To render the posts in the application, we need to add `app-posts` (the selector from `PostsComponent`) to the `app.component.html` file. In this file, replace the content with the following:

```html
<header role="banner">
  <img src="https://stepzen.comdata:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==" />
  <span>My posts</span>
</header>

<app-posts></app-posts>
```

4.  Finally, add styling to the `app.component.css` file:

```css
* {
    font-family: Arial, Helvetica, sans-serif;
    padding: 0;
}
header {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 60px;
    display: flex;
    align-items: center;
    background-color: #1976d2;
    color: white;
    font-weight: 600;
}
header img {
    margin: 0 16px;
}
```

The application should now look like this; make sure to run `npm start` to start the development server:

![Fetching GraphQL in an Angular application](https://stepzen.com/images/blog/graphql-angular-application.png)

But that's not all. You can also search posts by username. In the next section, we'll extend the functionality of this application by adding a search bar.

Adding search functionality
---------------------------

In this section, we'll add a search bar to the application to search for posts by username. With this functionality, we can search for posts by a specific user.

1.  For starters, we will add a new query to the `graphql.operations.ts` file. This query will take a username as an argument and return the same fields as the `GET_POSTS` query:

```typescript
// ...
const GET_POSTS_BY_USERNAME = gql`
    query GetPostsByUsername($username: String!) {
        posts(username: $username) {
            id
            title
            description
        }
  }
`

export { GET_POSTS, GET_POSTS_BY_USERNAME }
```

2.  From the file `posts/posts.component.ts`, we first need to import the built-in forms library `@angular/forms` and the `GET_POSTS_BY_USERNAME` query:

```typescript
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Apollo } from 'apollo-angular';
import { GET_POSTS, GET_POSTS_BY_USERNAME } from '../graphql.operations';
// ...
```

3.  In the same file, we will add a new method called `searchPosts` that will be called when the user submits the search form. This method will take the `GET_POSTS_BY_USERNAME` query and pass the username as an argument. The data for `posts` will be overwritten with the new data:

```typescript
// ...
export class PostsComponent implements OnInit {
  posts: any[] = [];
  error: any;
  searchForm = new FormGroup({
    username: new FormControl('gethackteam', Validators.required),
  });
  searchPosts() {
    this.apollo.query({
      query: GET_POSTS_BY_USERNAME,
      variables: {
        username: this.searchForm.value.username,
      }
    }).subscribe(({ data }: any) => {
      this.posts = data.posts;
    });
  }
```

3.  To add the search bar, we will add a `form` element to the markup file `posts.component.html`:

```html
<div class="main">
    <div *ngIf="error">
        <p>Error: {{ error }}</p>
    </div>
    <form class="form" [formGroup]="searchForm" (ngSubmit)="searchPosts()">
        <input class="input" type="text" name="username" placeholder="Enter username" formControlName="username" />
        <br />
        <button class="submit-button" [disabled]="searchForm.invalid">SUBMIT</button>
    </form>
    <!-- ... -->
```

4.  And to complete the search functionality, you can add the following styling rules to the bottom of the file `posts.component.css`:

```css
form {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
}
form input[type="text"] {
    padding: 5px 10px;
    margin-right: 10px;
}
form button {
    padding: 7px 12px;
    border: 0px;
    border-radius: 3px;
    background: #E23237;
    color: #FFF;
}
```

If you go to the Angular application running in your browser on `localhost` you can now search by username. A placeholder username is already present, and you can press the "submit" button to search for posts written by this username. Or, replace this value with your own username.

![Search for posts with an username](https://stepzen.com/images/blog/graphql-angular-application-with-search.png)

Congrats on building a fullstack Angular application! The final application should look something like the screenshot above. You can add features like error and loading status or routing to display an individual post to continue learning.

Conclusion
----------

This tutorial taught you to use GraphQL in an Angular application using Apollo Client. With Angular, you can build scalable frontend applications with native TypeScript support. On the other hand, Apollo Client is a library to help you fetish data from a GraphQL API. For example, the GraphQL API you created in this tutorial by transforming the DEV.to REST API into GraphQL using StepZen.

Head over to our [examples repository](https://github.com/stepzen-dev/examples) for more examples of using GraphQL and frontend libraries. Or the [StepZen docs](https://stepzen.com/docs/quick-start) to learn more about building GraphQL APIs? If you have questions about this tutorial, you can ask for help on our [Discord channel](https://discord.com/invite/9k2VdPn2FR).

***

This post was originally published on [stepzen.com](https://stepzen.com/blog/getting-started-with-graphql-in-angular). Reposted automatically with [Reposted.io](https://reposted.io?utm_source=postFooter).