{"componentChunkName":"component---src-pages-tutorial-angular-step-3-mdx","path":"/tutorial/angular/step-3/","result":{"pageContext":{"frontmatter":{"title":"3. Using APIs","tabs":["Overview","Step 1","Step 2","Step 3","Step 4","Step 5","Wrapping up"]},"relativePagePath":"/tutorial/angular/step-3.mdx","titleType":"prepend","MdxNode":{"id":"c39dc353-ccf0-5aca-9f63-90c5278b2582","children":[],"parent":"e426a2f5-bb17-56de-be23-66d845602799","internal":{"content":"---\ntitle: 3. Using APIs\ntabs:\n  ['Overview', 'Step 1', 'Step 2', 'Step 3', 'Step 4', 'Step 5', 'Wrapping up']\n---\n\nimport Preview from 'components/Preview';\n\n### This step takes our static components and populates them with data from the GitHub GraphQL API – loading states and all. We'll be displaying Carbon repository information in a data table.\n\n<AnchorLinks>\n\n<AnchorLink>Fork, clone and branch</AnchorLink>\n<AnchorLink>Install dependencies</AnchorLink>\n<AnchorLink>Create access token</AnchorLink>\n<AnchorLink>Connect to Apollo</AnchorLink>\n<AnchorLink>Fetch data</AnchorLink>\n<AnchorLink>Populate data table</AnchorLink>\n<AnchorLink>Add loading</AnchorLink>\n<AnchorLink>Add pagination</AnchorLink>\n<AnchorLink>Submit pull request</AnchorLink>\n\n</AnchorLinks>\n\n### Preview\n\nThe [GitHub GraphQL API](https://developer.github.com/v4/) is very well documented, and even though the focus of this tutorial isn't learning and using GraphQL, it's a great opportunity to fetch Carbon-related data for this Carbon tutorial.\n\nTo do so, we'll be using Apollo Client, the front-end component of the [Apollo Platform](https://www.apollographql.com/docs/intro/platform). Apollo provides several open source tools for using GraphQL throughout your application’s stack. Apollo Client is a sophisticated GraphQL client that manages data and state in an application.\n\nA [preview](https://angular-step-4-carbon-tutorial.netlify.com) of what you will build (see repositories page):\n\n<Preview\n  height=\"400\"\n  title=\"Carbon Tutorial Step 3\"\n  src=\"https://angular-step-4-carbon-tutorial.netlify.com\"\n  frameborder=\"no\"\n  allowtransparency=\"true\"\n  allowfullscreen=\"true\"\n/>\n\n<InlineNotification>\n\n**Note:** If you get lint errors when you copy the code from the snippets, run `ng lint --fix` to fix them.\n\n</InlineNotification>\n\n## Fork, clone and branch\n\nThis tutorial has an accompanying GitHub repository called [carbon-tutorial-angular](https://github.com/carbon-design-system/carbon-tutorial-angular) that we'll use as a starting point for each step. If you haven't forked and cloned that repository yet, and haven't added the upstream remote, go ahead and do so by following the [step 1 instructions](/tutorial/angular/step-1#fork-clone--branch).\n\n### Branch\n\nWith your repository all set up, let's check out the branch for this tutorial step's starting point.\n\n```bash\ngit fetch upstream\ngit checkout -b angular-step-3 upstream/angular-step-3\n```\n\n### Build and start app\n\nInstall the app's dependencies:\n\n```bash\nnpm install\n```\n\nThen, start the app:\n\n```bash\nnpm start\n```\n\nYou should see something similar to where the [previous step](/tutorial/angular/step-2) left off. Stop your app with `CTRL-C` and let's get everything installed.\n\n## Install dependencies\n\nWe'll shortcut this using the Angular CLI, if you'd like more information head over to [Angular Apollo Installation](https://www.apollographql.com/docs/angular/recipes/angular-cli/) for details.\n\n<InlineNotification>\n\n**Note:** If you have not yet installed the Angular CLI, you will need to [install the Angular CLI](https://cli.angular.io/) before running the Angular Apollo Installation.\n\n</InlineNotification>\n\nInstall the following\n\n- `apollo-client` - package containing everything you need to set up Apollo Client\n- `graphql` - parses your GraphQL queries\n- `apollo-angular` - Apollo integration for Angular\n\nUsing the command:\n\n```bash\nng add apollo-angular\nng lint --fix\n```\n\n<InlineNotification>\n\n​**Note:** In case you receive `ERROR in ../node_modules/graphql/subscription/subscribe.d.ts:44:3 - error TS2304: Cannot find name 'AsyncIterableIterator'.`, you'll have to add the code below\nin `tsconfig.app.json` `lib`: ​\n\n</InlineNotification>\n\n```javascript path=src/tsconfig.app.json\n\"lib\": [\n  \"es2016\",\n  \"dom\",\n  \"esnext.asynciterable\"\n],\n```\n\n<InlineNotification>\n\n**Note:** In case you receive `typings.d.ts:2:13 - error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type 'NodeModule', but here has type '{ id: string; }'.`, you'll have to comment out or remove the code below in `typings.d.ts`:\n\n</InlineNotification>\n\n```javascript path=src/typings.d.ts\ndeclare var module: {\n  id: string,\n};\n```\n\n## Create access token\n\nYou'll need a personal access token from your GitHub account in order to make requests to the GitHub API. Check out [this guide](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) to see how to get one.\n\nWhen you get to the scope/permissions step, you can leave them all unchecked. We don't need any special permissions, we just need access to the public API.\n\nOnce you have your token, we need to put it in a place where we can use it in our app. When your application is being built and developed, our app will parse environmental variables in any `environment` file and make them available.\n\n​<!-- prettier-ignore-start -->\n\n```javascript path=src/environment/environment.ts\nexport const environment = {\n  production: false,\n  githubPersonalAccessToken: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n```\n\n<!-- prettier-ignore-end -->\n\nGo ahead and start your app with `npm start`, or, if your app is running, you'll need to restart it to get access to this token.\n\n## Connect to Apollo\n\nWe need to import the environment at the top of every file that we decide to use it in:\n\n<!-- prettier-ignore-start -->\n```javascript\nimport { environment } from '../environments/environment';\n```\n<!-- prettier-ignore-end -->\n\nNext, make your client by providing a URI for the GitHub GraphQL API as well as an authorization header using the environmental variable you just added to `environment.ts`.\n\n<!-- prettier-ignore-start -->\n```javascript path=src/app/graphql.module.ts\nimport { HttpHeaders } from '@angular/common/http';\n\nconst uri = 'https://api.github.com/graphql'; // <-- add the URL of the GraphQL server here\nexport function createApollo(httpLink: HttpLink) {\n  return {\n    link: httpLink.create({\n      uri,\n      headers: new HttpHeaders({\n        Authorization: `Bearer ${environment.githubPersonalAccessToken}`,\n      }),\n    }),\n    cache: new InMemoryCache(),\n  };\n}\n```\n<!-- prettier-ignore-end -->\n\n## Fetch data\n\n### Imports\n\nAdd the following import at the top of `repo-table.component.ts`:\n\n<!-- prettier-ignore-start -->\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nimport { Apollo } from 'apollo-angular';\nimport gql from 'graphql-tag';\n```\n<!-- prettier-ignore-end -->\n\n### Query\n\nNext we'll assemble our GraphQL query to fetch only the data we need from the GraphQL API. We'll do this using the `gql` helper we just imported. The `gql` helper lets you write GraphQL queries using interpolated strings (backticks) in JavaScript.\n\nYou can use GitHub's [explorer](https://developer.github.com/v4/explorer/) tool to write and test your own queries. Try copying the query below and experiment with changing the properties. You can also click the \"Docs\" button in the top right of the explorer to view all of the available data and query parameters.\n\nIf you'd like some more information regarding writing queries, we recommend [Apollo's documentation](https://www.apollographql.com/docs/tutorial/queries) on this topic.\n\nFirst, we will add a private apollo parameter of type Apollo to the constructor to get access to the Apollo service.\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nconstructor(private apollo: Apollo) { }\n```\n\nNext, we will fetch the data in `ngOnInit()`. Add the folowing code right below the `model.header` declaration:\n\n```graphql path=src/app/repositories/repo-table/repo-table.component.ts\nthis.apollo.watchQuery({\n  query: gql`\n    query REPO_QUERY {\n      # Let's use carbon as our organization\n      organization(login: \"carbon-design-system\") {\n        # We'll grab all the repositories in one go. To load more resources\n        # continuously, see the advanced topics.\n        repositories(first: 75, orderBy: { field: UPDATED_AT, direction: DESC }) {\n          totalCount\n          nodes {\n            url\n            homepageUrl\n            issues(filterBy: { states: OPEN }) {\n              totalCount\n            }\n            stargazers {\n              totalCount\n            }\n            releases(first: 1) {\n              totalCount\n              nodes {\n                name\n              }\n            }\n            name\n            updatedAt\n            createdAt\n            description\n            id\n          }\n        }\n      }\n    }\n  `\n})\n```\n\n### Custom data\n\nOur last column in the data table will be a comma-separated list of repository and home page links, so let's create a custom cell template.\n\nThe column will have two values (`url` and `homepageUrl`) and will have the structure of an unordered list. If the repository does not have a home page URL, only render the repository link.\n\n```html path=src/app/repositories/repo-table/repo-table.component.html\n<ng-template #linkTemplate let-data=\"data\">\n  <ul style=\"display: flex\">\n    <li>\n      <a ibmLink [href]=\"data.github\">Github</a>\n    </li>\n    <li *ngIf=\"data.homepage\">\n      <span>&nbsp;|&nbsp;</span>\n      <a ibmLink [href]=\"data.homepage\">HomePage</a>\n    </li>\n  </ul>\n</ng-template>\n```\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\n@ViewChild('linkTemplate', null)\nprotected linkTemplate: TemplateRef<any>;\n```\n\n<InlineNotification>\n\n**Note:** Don't forget to import `ViewChild` and `TemplateRef`.\n\n</InlineNotification>\n\nNow let's create a function that transforms row data to our expected header keys. Notice how we're using our new `linkTemplate` to generate the value of the `links` key in each row.\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nprepareData(data) {\n  const newData = [];\n\n  for (const datum of data) {\n    newData.push([\n      new TableItem({ data: datum.name, expandedData: datum.description }),\n      new TableItem({ data: new Date(datum.createdAt).toLocaleDateString() }),\n      new TableItem({ data: new Date(datum.updatedAt).toLocaleDateString() }),\n      new TableItem({ data: datum.issues.totalCount }),\n      new TableItem({ data: datum.stargazers.totalCount }),\n      new TableItem({\n        data: {\n          github: datum.url,\n          homepage: datum.homepageUrl\n        },\n        template: this.linkTemplate\n      })\n    ]);\n  }\n  return newData;\n}\n```\n\n### Query component\n\nAt this point, we should run our query and `console.log()` the results to verify that the request is working.\n\nIf there's an issue, we'll render the corresponding error message. We will also check when loading is true, but add the implementation in the following steps.\n\nFinally, if neither of those are true, it means we have our data! One nice advantage of GraphQL is that as long as there are no errors, we can be certain the properties on the data we requested aren't `undefined`.\n\nAt the end of the `watchQuery` in `ngOnInit()`:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\n.valueChanges.subscribe((response: any) => {\n  if (response.error) {\n    const errorData = [];\n    errorData.push([\n      new TableItem({data: 'error!' })\n    ]);\n    this.model.data = errorData;\n  } else if (response.loading) {\n    // Add loading state\n  } else {\n    console.log(response);\n  }\n});\n```\n\nThe page will look the same as we're still rendering our static example rows, but if you view your browser's console (e.g. [Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/)), you should see the response from GitHub!\n\n## Populate data table\n\nNow that we have that data, let's populate the data table. Replace `console.log(response);` with the following that destructures the `organization` object. Once we have the repositories, we can call our `prepareData()` to build the data table rows.\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\n// If we're here, we've got our data!\nthis.prepareData(response.data.organization.repositories.nodes);\n```\n\nThen, in `ngOnInit()` delete the static rows since we no longer need them.\n\n## Add loading\n\nAt this point, the first time that you visit the repositories page, we're querying the GitHub API and rendering the response through the `DataTable` component. We could stop here, but there's more to be done! Let's add the [Table Skeleton](https://angular.carbondesignsystem.com/?path=/story/table--skeleton).\n\nTo do so, we will need to modify `repo-table.component.html` and `repo-table.component.ts`:\n\n<!-- prettier-ignore-start -->\n```html path=src/app/repositories/repo-table/repo-table.component.html\n<ibm-table\n  [skeleton]=\"skeleton\"\n  [model]=\"skeleton ? skeletonModel : model\"\n  [showSelectionColumn]=\"false\"\n  [striped]=\"false\">\n</ibm-table>\n```\n<!-- prettier-ignore-end -->\n\nWe need to tell the loading skeleton how many rows to render, so let's use 10 skeleton rows to prepare for the next enhancement...\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nskeletonModel = Table.skeletonModel(10, 6);\nskeleton = true;\n```\n\n<InlineNotification>\n\n**Note:** Don't forget to import `Table`.\n\n</InlineNotification>\n\nThen replace the comment with:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nelse if (response.loading) {\n  this.skeleton = true;\n}\n```\n\nand at the top of the `prepareData()` function add:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nthis.skeleton = false;\n```\n\n## Add pagination\n\nPagination! Instead of rendering every repository, let's add pagination to the data table to only render 10 at a time. Depending on your specific requirements, you may need to fetch new data each time that you interact with the pagination component, but for simplicity, we're going to make one request to fetch all data, and then paginate the in-memory row data.\n\nFirst we will create an array and populate it with 10 rows at a time.\n\n```javascript\ndata = [];\n```\n\nNext, replace the code where we call `preapreData()` with:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nthis.data = response.data.organization.repositories.nodes;\nthis.model.pageLength = 10;\nthis.model.totalDataLength = response.data.organization.repositories.totalCount;\nthis.selectPage(1);\n```\n\nThis initializes the page size to `10` as we also specified in our loading skeleton.\n\nNext we will call `selectPage()`. This will initialize the offset and use `prepareData()` to only render the subset of rows for the current \"page\".\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nselectPage(page) {\n  const offset = this.model.pageLength * (page - 1);\n  const pageRawData = this.data.slice(offset, offset + this.model.pageLength);\n  this.model.data = this.prepareData(pageRawData);\n  this.model.currentPage = page;\n}\n```\n\n<InlineNotification>\n\n**Note:** We only pass the rows that we want our table to display. We can do this by slicing our array of rows depending on the first item and the page size.\n\n</InlineNotification>\n\nFinally, let's import the `LinkModule` and `PaginationModule` to `repositories.module.ts` and `repo-table.component.spec` and add the template for pagination.\n\n```javascript path=src/app/repositories/repositories.module.ts,src/app/repositories/repo-table/repo-table.component.spec.ts\nimport { LinkModule, PaginationModule } from 'carbon-components-angular';\n```\n\n```javascript path=src/app/repositories/repositories.module.ts,src/app/repositories/repo-table/repo-table.component.spec.ts\nimports: [LinkModule, PaginationModule];\n```\n\nImmediately after the `ibm-table` closing tag (`/>`), add the `ibm-pagination` component.\n\n<!-- prettier-ignore-start -->\n```html path=src/app/repositories/repo-table/repo-table.component.html\n<ibm-pagination\n  [model]=\"model\"\n  (selectPage)=\"selectPage($event)\">\n</ibm-pagination>\n```\n<!-- prettier-ignore-end -->\n\n<InlineNotification>\n\n**Note:** Like the other Carbon Angular component, `pagination` component examples can be found in [Storybook](https://angular.carbondesignsystem.com/?path=/story/table--with-pagination) by browsing the story and knobs.\n\n</InlineNotification>\n\nThat does it! Your data table should fetch GitHub data on first render. You can expand each row to see the repository's description. You can modify the pagination items per page and cycle through pages or jump to a specific page of repositories.\n\n## Submit pull request\n\nWe're going to submit a pull request to verify completion of this tutorial step.\n\n### Continuous integration (CI) check\n\nRun the CI check to make sure we're all set to submit a pull request.\n\n```bash\nng lint --fix\nnpm run lint && npm test\n```\n\n<InlineNotification>\n\n**Note:** Having issues running the CI check? [Step 1](</tutorial/angular/step-1#continuous-integration-(ci)-check>) has troubleshooting notes that may help.\n\n</InlineNotification>\n\n### Git commit and push\n\nBefore we can create a pull request, stage and commit all of your changes:\n\n```bash\ngit add --all && git commit -m \"feat(tutorial): complete step 3\"\n```\n\nThen, push to your repository:\n\n```bash\ngit push origin angular-step-3\n```\n\n<InlineNotification>\n\n**Note:** Having issues pushing your changes? [Step 1](/tutorial/angular/step-1#git-commit-and-push) has troubleshooting notes that may help.\n\n</InlineNotification>\n\n### Pull request (PR)\n\nFinally, visit [carbon-tutorial-angular](https://github.com/carbon-design-system/carbon-tutorial-angular) to \"Compare & pull request\". In doing so, make sure that you are comparing to `angular-step-3` into `base: angular-step-3`.\n\n<InlineNotification>\n\n**Note:** Expect your tutorial step PRs to be reviewed by the Carbon team but not merged. We'll close your PR so we can keep the repository's remote branches pristine and ready for the next person!\n\n</InlineNotification>\n","type":"Mdx","contentDigest":"bac46d64107adbac2fb43f4cd1cf686f","counter":1669,"owner":"gatsby-plugin-mdx"},"frontmatter":{"title":"3. Using APIs","tabs":["Overview","Step 1","Step 2","Step 3","Step 4","Step 5","Wrapping up"]},"exports":{},"rawBody":"---\ntitle: 3. Using APIs\ntabs:\n  ['Overview', 'Step 1', 'Step 2', 'Step 3', 'Step 4', 'Step 5', 'Wrapping up']\n---\n\nimport Preview from 'components/Preview';\n\n### This step takes our static components and populates them with data from the GitHub GraphQL API – loading states and all. We'll be displaying Carbon repository information in a data table.\n\n<AnchorLinks>\n\n<AnchorLink>Fork, clone and branch</AnchorLink>\n<AnchorLink>Install dependencies</AnchorLink>\n<AnchorLink>Create access token</AnchorLink>\n<AnchorLink>Connect to Apollo</AnchorLink>\n<AnchorLink>Fetch data</AnchorLink>\n<AnchorLink>Populate data table</AnchorLink>\n<AnchorLink>Add loading</AnchorLink>\n<AnchorLink>Add pagination</AnchorLink>\n<AnchorLink>Submit pull request</AnchorLink>\n\n</AnchorLinks>\n\n### Preview\n\nThe [GitHub GraphQL API](https://developer.github.com/v4/) is very well documented, and even though the focus of this tutorial isn't learning and using GraphQL, it's a great opportunity to fetch Carbon-related data for this Carbon tutorial.\n\nTo do so, we'll be using Apollo Client, the front-end component of the [Apollo Platform](https://www.apollographql.com/docs/intro/platform). Apollo provides several open source tools for using GraphQL throughout your application’s stack. Apollo Client is a sophisticated GraphQL client that manages data and state in an application.\n\nA [preview](https://angular-step-4-carbon-tutorial.netlify.com) of what you will build (see repositories page):\n\n<Preview\n  height=\"400\"\n  title=\"Carbon Tutorial Step 3\"\n  src=\"https://angular-step-4-carbon-tutorial.netlify.com\"\n  frameborder=\"no\"\n  allowtransparency=\"true\"\n  allowfullscreen=\"true\"\n/>\n\n<InlineNotification>\n\n**Note:** If you get lint errors when you copy the code from the snippets, run `ng lint --fix` to fix them.\n\n</InlineNotification>\n\n## Fork, clone and branch\n\nThis tutorial has an accompanying GitHub repository called [carbon-tutorial-angular](https://github.com/carbon-design-system/carbon-tutorial-angular) that we'll use as a starting point for each step. If you haven't forked and cloned that repository yet, and haven't added the upstream remote, go ahead and do so by following the [step 1 instructions](/tutorial/angular/step-1#fork-clone--branch).\n\n### Branch\n\nWith your repository all set up, let's check out the branch for this tutorial step's starting point.\n\n```bash\ngit fetch upstream\ngit checkout -b angular-step-3 upstream/angular-step-3\n```\n\n### Build and start app\n\nInstall the app's dependencies:\n\n```bash\nnpm install\n```\n\nThen, start the app:\n\n```bash\nnpm start\n```\n\nYou should see something similar to where the [previous step](/tutorial/angular/step-2) left off. Stop your app with `CTRL-C` and let's get everything installed.\n\n## Install dependencies\n\nWe'll shortcut this using the Angular CLI, if you'd like more information head over to [Angular Apollo Installation](https://www.apollographql.com/docs/angular/recipes/angular-cli/) for details.\n\n<InlineNotification>\n\n**Note:** If you have not yet installed the Angular CLI, you will need to [install the Angular CLI](https://cli.angular.io/) before running the Angular Apollo Installation.\n\n</InlineNotification>\n\nInstall the following\n\n- `apollo-client` - package containing everything you need to set up Apollo Client\n- `graphql` - parses your GraphQL queries\n- `apollo-angular` - Apollo integration for Angular\n\nUsing the command:\n\n```bash\nng add apollo-angular\nng lint --fix\n```\n\n<InlineNotification>\n\n​**Note:** In case you receive `ERROR in ../node_modules/graphql/subscription/subscribe.d.ts:44:3 - error TS2304: Cannot find name 'AsyncIterableIterator'.`, you'll have to add the code below\nin `tsconfig.app.json` `lib`: ​\n\n</InlineNotification>\n\n```javascript path=src/tsconfig.app.json\n\"lib\": [\n  \"es2016\",\n  \"dom\",\n  \"esnext.asynciterable\"\n],\n```\n\n<InlineNotification>\n\n**Note:** In case you receive `typings.d.ts:2:13 - error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type 'NodeModule', but here has type '{ id: string; }'.`, you'll have to comment out or remove the code below in `typings.d.ts`:\n\n</InlineNotification>\n\n```javascript path=src/typings.d.ts\ndeclare var module: {\n  id: string,\n};\n```\n\n## Create access token\n\nYou'll need a personal access token from your GitHub account in order to make requests to the GitHub API. Check out [this guide](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) to see how to get one.\n\nWhen you get to the scope/permissions step, you can leave them all unchecked. We don't need any special permissions, we just need access to the public API.\n\nOnce you have your token, we need to put it in a place where we can use it in our app. When your application is being built and developed, our app will parse environmental variables in any `environment` file and make them available.\n\n​<!-- prettier-ignore-start -->\n\n```javascript path=src/environment/environment.ts\nexport const environment = {\n  production: false,\n  githubPersonalAccessToken: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n```\n\n<!-- prettier-ignore-end -->\n\nGo ahead and start your app with `npm start`, or, if your app is running, you'll need to restart it to get access to this token.\n\n## Connect to Apollo\n\nWe need to import the environment at the top of every file that we decide to use it in:\n\n<!-- prettier-ignore-start -->\n```javascript\nimport { environment } from '../environments/environment';\n```\n<!-- prettier-ignore-end -->\n\nNext, make your client by providing a URI for the GitHub GraphQL API as well as an authorization header using the environmental variable you just added to `environment.ts`.\n\n<!-- prettier-ignore-start -->\n```javascript path=src/app/graphql.module.ts\nimport { HttpHeaders } from '@angular/common/http';\n\nconst uri = 'https://api.github.com/graphql'; // <-- add the URL of the GraphQL server here\nexport function createApollo(httpLink: HttpLink) {\n  return {\n    link: httpLink.create({\n      uri,\n      headers: new HttpHeaders({\n        Authorization: `Bearer ${environment.githubPersonalAccessToken}`,\n      }),\n    }),\n    cache: new InMemoryCache(),\n  };\n}\n```\n<!-- prettier-ignore-end -->\n\n## Fetch data\n\n### Imports\n\nAdd the following import at the top of `repo-table.component.ts`:\n\n<!-- prettier-ignore-start -->\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nimport { Apollo } from 'apollo-angular';\nimport gql from 'graphql-tag';\n```\n<!-- prettier-ignore-end -->\n\n### Query\n\nNext we'll assemble our GraphQL query to fetch only the data we need from the GraphQL API. We'll do this using the `gql` helper we just imported. The `gql` helper lets you write GraphQL queries using interpolated strings (backticks) in JavaScript.\n\nYou can use GitHub's [explorer](https://developer.github.com/v4/explorer/) tool to write and test your own queries. Try copying the query below and experiment with changing the properties. You can also click the \"Docs\" button in the top right of the explorer to view all of the available data and query parameters.\n\nIf you'd like some more information regarding writing queries, we recommend [Apollo's documentation](https://www.apollographql.com/docs/tutorial/queries) on this topic.\n\nFirst, we will add a private apollo parameter of type Apollo to the constructor to get access to the Apollo service.\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nconstructor(private apollo: Apollo) { }\n```\n\nNext, we will fetch the data in `ngOnInit()`. Add the folowing code right below the `model.header` declaration:\n\n```graphql path=src/app/repositories/repo-table/repo-table.component.ts\nthis.apollo.watchQuery({\n  query: gql`\n    query REPO_QUERY {\n      # Let's use carbon as our organization\n      organization(login: \"carbon-design-system\") {\n        # We'll grab all the repositories in one go. To load more resources\n        # continuously, see the advanced topics.\n        repositories(first: 75, orderBy: { field: UPDATED_AT, direction: DESC }) {\n          totalCount\n          nodes {\n            url\n            homepageUrl\n            issues(filterBy: { states: OPEN }) {\n              totalCount\n            }\n            stargazers {\n              totalCount\n            }\n            releases(first: 1) {\n              totalCount\n              nodes {\n                name\n              }\n            }\n            name\n            updatedAt\n            createdAt\n            description\n            id\n          }\n        }\n      }\n    }\n  `\n})\n```\n\n### Custom data\n\nOur last column in the data table will be a comma-separated list of repository and home page links, so let's create a custom cell template.\n\nThe column will have two values (`url` and `homepageUrl`) and will have the structure of an unordered list. If the repository does not have a home page URL, only render the repository link.\n\n```html path=src/app/repositories/repo-table/repo-table.component.html\n<ng-template #linkTemplate let-data=\"data\">\n  <ul style=\"display: flex\">\n    <li>\n      <a ibmLink [href]=\"data.github\">Github</a>\n    </li>\n    <li *ngIf=\"data.homepage\">\n      <span>&nbsp;|&nbsp;</span>\n      <a ibmLink [href]=\"data.homepage\">HomePage</a>\n    </li>\n  </ul>\n</ng-template>\n```\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\n@ViewChild('linkTemplate', null)\nprotected linkTemplate: TemplateRef<any>;\n```\n\n<InlineNotification>\n\n**Note:** Don't forget to import `ViewChild` and `TemplateRef`.\n\n</InlineNotification>\n\nNow let's create a function that transforms row data to our expected header keys. Notice how we're using our new `linkTemplate` to generate the value of the `links` key in each row.\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nprepareData(data) {\n  const newData = [];\n\n  for (const datum of data) {\n    newData.push([\n      new TableItem({ data: datum.name, expandedData: datum.description }),\n      new TableItem({ data: new Date(datum.createdAt).toLocaleDateString() }),\n      new TableItem({ data: new Date(datum.updatedAt).toLocaleDateString() }),\n      new TableItem({ data: datum.issues.totalCount }),\n      new TableItem({ data: datum.stargazers.totalCount }),\n      new TableItem({\n        data: {\n          github: datum.url,\n          homepage: datum.homepageUrl\n        },\n        template: this.linkTemplate\n      })\n    ]);\n  }\n  return newData;\n}\n```\n\n### Query component\n\nAt this point, we should run our query and `console.log()` the results to verify that the request is working.\n\nIf there's an issue, we'll render the corresponding error message. We will also check when loading is true, but add the implementation in the following steps.\n\nFinally, if neither of those are true, it means we have our data! One nice advantage of GraphQL is that as long as there are no errors, we can be certain the properties on the data we requested aren't `undefined`.\n\nAt the end of the `watchQuery` in `ngOnInit()`:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\n.valueChanges.subscribe((response: any) => {\n  if (response.error) {\n    const errorData = [];\n    errorData.push([\n      new TableItem({data: 'error!' })\n    ]);\n    this.model.data = errorData;\n  } else if (response.loading) {\n    // Add loading state\n  } else {\n    console.log(response);\n  }\n});\n```\n\nThe page will look the same as we're still rendering our static example rows, but if you view your browser's console (e.g. [Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/)), you should see the response from GitHub!\n\n## Populate data table\n\nNow that we have that data, let's populate the data table. Replace `console.log(response);` with the following that destructures the `organization` object. Once we have the repositories, we can call our `prepareData()` to build the data table rows.\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\n// If we're here, we've got our data!\nthis.prepareData(response.data.organization.repositories.nodes);\n```\n\nThen, in `ngOnInit()` delete the static rows since we no longer need them.\n\n## Add loading\n\nAt this point, the first time that you visit the repositories page, we're querying the GitHub API and rendering the response through the `DataTable` component. We could stop here, but there's more to be done! Let's add the [Table Skeleton](https://angular.carbondesignsystem.com/?path=/story/table--skeleton).\n\nTo do so, we will need to modify `repo-table.component.html` and `repo-table.component.ts`:\n\n<!-- prettier-ignore-start -->\n```html path=src/app/repositories/repo-table/repo-table.component.html\n<ibm-table\n  [skeleton]=\"skeleton\"\n  [model]=\"skeleton ? skeletonModel : model\"\n  [showSelectionColumn]=\"false\"\n  [striped]=\"false\">\n</ibm-table>\n```\n<!-- prettier-ignore-end -->\n\nWe need to tell the loading skeleton how many rows to render, so let's use 10 skeleton rows to prepare for the next enhancement...\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nskeletonModel = Table.skeletonModel(10, 6);\nskeleton = true;\n```\n\n<InlineNotification>\n\n**Note:** Don't forget to import `Table`.\n\n</InlineNotification>\n\nThen replace the comment with:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nelse if (response.loading) {\n  this.skeleton = true;\n}\n```\n\nand at the top of the `prepareData()` function add:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nthis.skeleton = false;\n```\n\n## Add pagination\n\nPagination! Instead of rendering every repository, let's add pagination to the data table to only render 10 at a time. Depending on your specific requirements, you may need to fetch new data each time that you interact with the pagination component, but for simplicity, we're going to make one request to fetch all data, and then paginate the in-memory row data.\n\nFirst we will create an array and populate it with 10 rows at a time.\n\n```javascript\ndata = [];\n```\n\nNext, replace the code where we call `preapreData()` with:\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nthis.data = response.data.organization.repositories.nodes;\nthis.model.pageLength = 10;\nthis.model.totalDataLength = response.data.organization.repositories.totalCount;\nthis.selectPage(1);\n```\n\nThis initializes the page size to `10` as we also specified in our loading skeleton.\n\nNext we will call `selectPage()`. This will initialize the offset and use `prepareData()` to only render the subset of rows for the current \"page\".\n\n```javascript path=src/app/repositories/repo-table/repo-table.component.ts\nselectPage(page) {\n  const offset = this.model.pageLength * (page - 1);\n  const pageRawData = this.data.slice(offset, offset + this.model.pageLength);\n  this.model.data = this.prepareData(pageRawData);\n  this.model.currentPage = page;\n}\n```\n\n<InlineNotification>\n\n**Note:** We only pass the rows that we want our table to display. We can do this by slicing our array of rows depending on the first item and the page size.\n\n</InlineNotification>\n\nFinally, let's import the `LinkModule` and `PaginationModule` to `repositories.module.ts` and `repo-table.component.spec` and add the template for pagination.\n\n```javascript path=src/app/repositories/repositories.module.ts,src/app/repositories/repo-table/repo-table.component.spec.ts\nimport { LinkModule, PaginationModule } from 'carbon-components-angular';\n```\n\n```javascript path=src/app/repositories/repositories.module.ts,src/app/repositories/repo-table/repo-table.component.spec.ts\nimports: [LinkModule, PaginationModule];\n```\n\nImmediately after the `ibm-table` closing tag (`/>`), add the `ibm-pagination` component.\n\n<!-- prettier-ignore-start -->\n```html path=src/app/repositories/repo-table/repo-table.component.html\n<ibm-pagination\n  [model]=\"model\"\n  (selectPage)=\"selectPage($event)\">\n</ibm-pagination>\n```\n<!-- prettier-ignore-end -->\n\n<InlineNotification>\n\n**Note:** Like the other Carbon Angular component, `pagination` component examples can be found in [Storybook](https://angular.carbondesignsystem.com/?path=/story/table--with-pagination) by browsing the story and knobs.\n\n</InlineNotification>\n\nThat does it! Your data table should fetch GitHub data on first render. You can expand each row to see the repository's description. You can modify the pagination items per page and cycle through pages or jump to a specific page of repositories.\n\n## Submit pull request\n\nWe're going to submit a pull request to verify completion of this tutorial step.\n\n### Continuous integration (CI) check\n\nRun the CI check to make sure we're all set to submit a pull request.\n\n```bash\nng lint --fix\nnpm run lint && npm test\n```\n\n<InlineNotification>\n\n**Note:** Having issues running the CI check? [Step 1](</tutorial/angular/step-1#continuous-integration-(ci)-check>) has troubleshooting notes that may help.\n\n</InlineNotification>\n\n### Git commit and push\n\nBefore we can create a pull request, stage and commit all of your changes:\n\n```bash\ngit add --all && git commit -m \"feat(tutorial): complete step 3\"\n```\n\nThen, push to your repository:\n\n```bash\ngit push origin angular-step-3\n```\n\n<InlineNotification>\n\n**Note:** Having issues pushing your changes? [Step 1](/tutorial/angular/step-1#git-commit-and-push) has troubleshooting notes that may help.\n\n</InlineNotification>\n\n### Pull request (PR)\n\nFinally, visit [carbon-tutorial-angular](https://github.com/carbon-design-system/carbon-tutorial-angular) to \"Compare & pull request\". In doing so, make sure that you are comparing to `angular-step-3` into `base: angular-step-3`.\n\n<InlineNotification>\n\n**Note:** Expect your tutorial step PRs to be reviewed by the Carbon team but not merged. We'll close your PR so we can keep the repository's remote branches pristine and ready for the next person!\n\n</InlineNotification>\n","fileAbsolutePath":"/zeit/767b4790/src/pages/tutorial/angular/step-3.mdx"}}}}