Skip to content

Commit

Permalink
docs(angular-query): add pagination example
Browse files Browse the repository at this point in the history
  • Loading branch information
arnoud-dv committed Oct 3, 2024
1 parent 69476f0 commit da1e410
Show file tree
Hide file tree
Showing 29 changed files with 529 additions and 41 deletions.
2 changes: 1 addition & 1 deletion examples/angular/basic/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Angular Query basic example
# TanStack Query Angular basic example

To run this example:

Expand Down
2 changes: 1 addition & 1 deletion examples/angular/basic/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withFetch()),
provideAngularQuery(
new QueryClient({
defaultOptions: {
Expand All @@ -17,5 +16,6 @@ export const appConfig: ApplicationConfig = {
},
}),
),
provideHttpClient(withFetch()),
],
}
2 changes: 1 addition & 1 deletion examples/angular/basic/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<basic-example />
<basic-example></basic-example>
</body>
</html>
2 changes: 1 addition & 1 deletion examples/angular/infinite-query-with-max-pages/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Angular Query infinite query example
# TanStack Query Angular infinite query example

To run this example:

Expand Down
10 changes: 5 additions & 5 deletions examples/angular/infinite-query-with-max-pages/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"newProjectRoot": "projects",
"projects": {
"basic": {
"infinite-query-with-max-pages": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
Expand Down Expand Up @@ -47,7 +47,7 @@
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "dist/basic",
"outputPath": "dist/infinite-query-with-max-pages",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": ["zone.js"],
Expand Down Expand Up @@ -84,18 +84,18 @@
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "basic:build:production"
"buildTarget": "infinite-query-with-max-pages:build:production"
},
"development": {
"buildTarget": "basic:build:development"
"buildTarget": "infinite-query-with-max-pages:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "basic:build"
"buildTarget": "infinite-query-with-max-pages:build"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptors([projectsMockInterceptor]), withFetch()),
provideAngularQuery(
new QueryClient({
defaultOptions: {
Expand All @@ -22,5 +21,6 @@ export const appConfig: ApplicationConfig = {
},
}),
),
provideHttpClient(withInterceptors([projectsMockInterceptor]), withFetch()),
],
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimen
import { injectInfiniteQuery } from '@tanstack/angular-query-experimental'
import { lastValueFrom } from 'rxjs'
import { ProjectStyleDirective } from '../directives/project-style.directive'
import { ProjectsService } from '../services/projects-service'
import { ProjectsService } from '../services/projects.service'

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
Expand Down
4 changes: 2 additions & 2 deletions examples/angular/infinite-query-with-max-pages/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Angular Query infinite query example</title>
<title>TanStack Query Angular infinite query example</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root />
<app-root></app-root>
</body>
</html>
6 changes: 6 additions & 0 deletions examples/angular/pagination/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# TanStack Query Angular pagination example

To run this example:

- `npm install` or `yarn` or `pnpm i` or `bun i`
- `npm run start` or `yarn start` or `pnpm start` or `bun start`
104 changes: 104 additions & 0 deletions examples/angular/pagination/angular.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "pnpm",
"analytics": false,
"cache": {
"enabled": false
}
},
"newProjectRoot": "projects",
"projects": {
"pagination": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"inlineTemplate": true,
"inlineStyle": true,
"skipTests": true
},
"@schematics/angular:class": {
"skipTests": true
},
"@schematics/angular:directive": {
"skipTests": true
},
"@schematics/angular:guard": {
"skipTests": true
},
"@schematics/angular:interceptor": {
"skipTests": true
},
"@schematics/angular:pipe": {
"skipTests": true
},
"@schematics/angular:resolver": {
"skipTests": true
},
"@schematics/angular:service": {
"skipTests": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "dist/pagination",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"assets": ["src/favicon.ico"],
"styles": [],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "pagination:build:production"
},
"development": {
"buildTarget": "pagination:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "pagination:build"
}
}
}
}
}
}
29 changes: 29 additions & 0 deletions examples/angular/pagination/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@tanstack/query-example-angular-pagination",
"private": true,
"type": "module",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development"
},
"dependencies": {
"@angular/common": "^17.3.12",
"@angular/compiler": "^17.3.12",
"@angular/core": "^17.3.12",
"@angular/platform-browser": "^17.3.12",
"@angular/platform-browser-dynamic": "^17.3.12",
"@tanstack/angular-query-experimental": "^5.59.0",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"zone.js": "^0.14.8"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.3.8",
"@angular/cli": "^17.3.8",
"@angular/compiler-cli": "^17.3.12",
"@tanstack/angular-query-devtools-experimental": "^5.59.0",
"typescript": "5.3.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { HttpResponse } from '@angular/common/http'
import { delay, of } from 'rxjs'
import type { Observable } from 'rxjs'
import type { HttpEvent, HttpInterceptorFn } from '@angular/common/http'

export const projectsMockInterceptor: HttpInterceptorFn = (
req,
next,
): Observable<HttpEvent<any>> => {
const { url } = req

if (url.includes('/api/projects')) {
const page = parseInt(
new URLSearchParams(req.url.split('?')[1]).get('page') || '0',
10,
)
const pageSize = 10

const projects = Array(pageSize)
.fill(0)
.map((_, i) => {
const id = page * pageSize + (i + 1)
return {
name: 'Project ' + id,
id,
}
})

return of(
new HttpResponse({
status: 200,
body: {
projects,
hasMore: page < 9,
},
}),
).pipe(delay(1000))
}
return next(req)
}
12 changes: 12 additions & 0 deletions examples/angular/pagination/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
import { ExampleComponent } from './components/example.component'

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-root',
standalone: true,
template: `<example /><angular-query-devtools initialIsOpen />`,
imports: [AngularQueryDevtools, ExampleComponent],
})
export class AppComponent {}
18 changes: 18 additions & 0 deletions examples/angular/pagination/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
provideHttpClient,
withFetch,
withInterceptors,
} from '@angular/common/http'
import {
QueryClient,
provideAngularQuery,
} from '@tanstack/angular-query-experimental'
import { projectsMockInterceptor } from './api/projects-mock.interceptor'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
provideAngularQuery(new QueryClient()),
provideHttpClient(withInterceptors([projectsMockInterceptor]), withFetch()),
],
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<div>
<p>
In this example, each page of data remains visible as the next page is
fetched. The buttons and capability to proceed to the next page are also
supressed until the next page cursor is known. Each page is cached as a
normal query too, so when going to previous pages, you'll see them
instantaneously while they are also refetched invisibly in the background.
</p>

@if (query.isPending()) {
<div>Loading...</div>
} @else if (query.isError()) {
<div>Error: {{ query.error().message }}</div>
} @else if (query.isSuccess()) {
<div>
@for (project of query.data().projects; track project.id) {
<p>{{ project.name }}</p>
}
</div>
}

<div>Current Page: {{ page() + 1 }}</div>

<button (click)="previousPage()" [disabled]="page() === 0">
Previous Page
</button>
<button
(click)="nextPage()"
[disabled]="query.isPlaceholderData() || !query.data()?.hasMore"
>
Next Page
</button>
<!-- Since the last page's data potentially sticks around between page requests, -->
<!-- we can use `isFetching` to show a background loading -->
<!-- indicator since our `status === 'pending'` state won't be triggered -->
@if(query.isFetching()) {
<span>Loading...</span>
}
<angular-query-devtools initialIsOpen />
</div>
Loading

0 comments on commit da1e410

Please sign in to comment.