Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular persist query client experimental #8324

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f327a5d
feat(angular-query):
OmerGronich Nov 29, 2024
dd92bfc
feat(angular-query): created package for experimental persistence sup…
OmerGronich Nov 22, 2024
b8afd8a
test(persistQuery): add tests for withPersistQueryClient
OmerGronich Nov 23, 2024
547ae9e
docs(angular-query): add basic persister example
OmerGronich Nov 23, 2024
7130913
fix(angular-query): synced angular versions in new package
OmerGronich Nov 29, 2024
5709184
fix(angular-query): commit before ng update
OmerGronich Nov 29, 2024
9e6ef24
feat(angular-query): updated example to v18
OmerGronich Nov 29, 2024
962cf32
fix(angular-query): fixed project name to basic-persister
OmerGronich Nov 29, 2024
4d305a5
feat(angular-query): updated example basic-persister to v19
OmerGronich Nov 29, 2024
630e462
feat(angular-query): included back the persister package after angula…
OmerGronich Nov 29, 2024
fed1caa
feat(angular-query): migrate to provideEnvironmentInitializer
OmerGronich Nov 29, 2024
63831fb
fix(angular-query): fix eslint issues in inject-queries.ts
OmerGronich Nov 29, 2024
059b620
Revert "feat(angular-query): migrate to provideEnvironmentInitializer"
OmerGronich Nov 29, 2024
05848e2
fix(angular-query): only track the isRestoring in the effect
OmerGronich Nov 29, 2024
a0d3111
fix(angular-query): removed conditional _isRestoring
OmerGronich Nov 29, 2024
e2f579b
ci: apply automated fixes
autofix-ci[bot] Nov 29, 2024
929b114
fix(angular-query): used effect onCleanup instead of destroy ref
OmerGronich Nov 29, 2024
9dcdd1c
Update examples/angular/basic-persister/.devcontainer/devcontainer.json
OmerGronich Dec 6, 2024
f208029
Update examples/angular/basic-persister/package.json
OmerGronich Dec 6, 2024
1d3c67a
Update examples/angular/basic-persister/src/index.html
OmerGronich Dec 6, 2024
db2b2a3
Update examples/angular/basic-persister/tsconfig.json
OmerGronich Dec 6, 2024
de5b14f
Update examples/angular/basic-persister/tsconfig.json
OmerGronich Dec 6, 2024
03b9c02
Update examples/angular/basic-persister/tsconfig.json
OmerGronich Dec 6, 2024
67d3f38
Update packages/angular-query-experimental/src/inject-is-restoring.ts
OmerGronich Dec 6, 2024
b30b21b
fix(angular-query): fixed lock file
OmerGronich Dec 6, 2024
c9ec26a
fix(angular-query): aligned package.json versions
OmerGronich Dec 6, 2024
b858927
added missing dep from basic-persister example
OmerGronich Dec 6, 2024
325b2a7
Added a more complex example for persistence. This examples demonstra…
OmerGronich Dec 6, 2024
c908304
Merge remote-tracking branch 'upstream/main' into angular-persist-que…
OmerGronich Dec 8, 2024
5da9025
fix(angular-query) bumped versions to 5.62.4
OmerGronich Dec 8, 2024
36605e6
refactor(angular-query) refactored to implicit return
OmerGronich Dec 8, 2024
a5f7942
Merge remote-tracking branch 'upstream/main' into angular-persist-que…
OmerGronich Dec 10, 2024
5d80309
fix(angular-query) bump angular persister package and examples version
OmerGronich Dec 10, 2024
ffa43a8
fix(angular-query) fixed eslint errors
OmerGronich Dec 13, 2024
235bbab
refactor(angular-query) set initial `isRestoring` to true to match th…
OmerGronich Dec 13, 2024
1f33c28
Revert "refactor(angular-query) set initial `isRestoring` to true to …
OmerGronich Dec 13, 2024
23d6ee1
fix(angular-query) fixed formatting of JSDOC comment ruined by eslint
OmerGronich Dec 13, 2024
2e8bfe9
Merge branch 'main' into angular-persist-query-client-experimental
OmerGronich Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "Node.js",
"image": "mcr.microsoft.com/devcontainers/javascript-node:22"
}
6 changes: 6 additions & 0 deletions examples/angular/basic-persister/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// @ts-check

/** @type {import('eslint').Linter.Config} */
const config = {}

module.exports = config
6 changes: 6 additions & 0 deletions examples/angular/basic-persister/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# TanStack Query Angular basic persister 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/basic-persister/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": {
"basic-persister": {
"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/build:application",
"options": {
"outputPath": "dist/basic-persister",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"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/build:dev-server",
"configurations": {
"production": {
"buildTarget": "basic-persister:build:production"
},
"development": {
"buildTarget": "basic-persister:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular/build:extract-i18n",
"options": {
"buildTarget": "basic-persister:build"
}
}
}
}
}
}
30 changes: 30 additions & 0 deletions examples/angular/basic-persister/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@tanstack/query-example-angular-basic-persister",
"type": "module",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development"
},
"private": true,
"dependencies": {
"@angular/common": "^19.1.0-next.0",
"@angular/compiler": "^19.1.0-next.0",
"@angular/core": "^19.1.0-next.0",
"@angular/platform-browser": "^19.1.0-next.0",
"@angular/platform-browser-dynamic": "^19.1.0-next.0",
"@tanstack/angular-query-experimental": "^5.62.7",
"@tanstack/angular-query-persist-client-experimental": "^5.62.7",
"@tanstack/query-sync-storage-persister": "^5.62.3",
"rxjs": "^7.8.1",
"tslib": "^2.6.3",
"zone.js": "^0.15.0"
},
"devDependencies": {
"@angular/build": "^19.0.2",
"@angular/cli": "^19.0.2",
"@angular/compiler-cli": "^19.1.0-next.0",
"typescript": "5.7.2"
}
}
10 changes: 10 additions & 0 deletions examples/angular/basic-persister/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p>
Try to mock offline behavior with the button in the devtools. You can navigate
around as long as there is already data in the cache. You'll get a refetch as
soon as you go "online" again.
</p>
@if (postId() > -1) {
<post [postId]="postId()" (setPostId)="postId.set($event)"></post>
} @else {
<posts (setPostId)="postId.set($event)" />
}
13 changes: 13 additions & 0 deletions examples/angular/basic-persister/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ChangeDetectionStrategy, Component, signal } from '@angular/core'
import { PostComponent } from './components/post.component'
import { PostsComponent } from './components/posts.component'

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'basic-example',
templateUrl: './app.component.html',
imports: [PostComponent, PostsComponent],
})
export class BasicExampleComponent {
postId = signal(-1)
}
37 changes: 37 additions & 0 deletions examples/angular/basic-persister/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { provideHttpClient, withFetch } from '@angular/common/http'
import {
QueryClient,
provideTanStackQuery,
withDevtools,
} from '@tanstack/angular-query-experimental'
import { withPersistQueryClient } from '@tanstack/angular-query-persist-client-experimental'
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
import type { ApplicationConfig } from '@angular/core'

const localStoragePersister = createSyncStoragePersister({
storage: window.localStorage,
})

export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withFetch()),
provideTanStackQuery(
new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60,
gcTime: 1000 * 60 * 60 * 24, // 24 hours
},
},
}),
withDevtools(),
withPersistQueryClient([
OmerGronich marked this conversation as resolved.
Show resolved Hide resolved
{
persistOptions: {
persister: localStoragePersister,
},
},
]),
),
],
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div>
<div>
<a (click)="setPostId.emit(-1)" href="#"> Back </a>
</div>
@if (postQuery.isPending()) {
Loading...
} @else if (postQuery.isError()) {
Error: {{ postQuery.error().message }}
}
@if (postQuery.data(); as post) {
<h1>{{ post.title }}</h1>
<div>
<p>{{ post.body }}</p>
</div>
@if (postQuery.isFetching()) {
Background Updating...
}
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Output,
inject,
input,
} from '@angular/core'
import { QueryClient, injectQuery } from '@tanstack/angular-query-experimental'
import { fromEvent, lastValueFrom, takeUntil } from 'rxjs'
import { PostsService } from '../services/posts-service'

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'post',
standalone: true,
templateUrl: './post.component.html',
})
export class PostComponent {
#postsService = inject(PostsService)

@Output() setPostId = new EventEmitter<number>()

postId = input(0)

postQuery = injectQuery(() => ({
enabled: this.postId() > 0,
queryKey: ['post', this.postId()],
queryFn: async (context) => {
// Cancels the request when component is destroyed before the request finishes
const abort$ = fromEvent(context.signal, 'abort')
return lastValueFrom(
this.#postsService.postById$(this.postId()).pipe(takeUntil(abort$)),
)
},
}))

queryClient = inject(QueryClient)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div>
<h1>Posts</h1>
@switch (postsQuery.status()) {
@case ('pending') {
Loading...
}
@case ('error') {
Error: {{ postsQuery.error()?.message }}
}
@default {
<div class="todo-container">
@for (post of postsQuery.data(); track post.id) {
<p>
<!-- We can access the query data here to show bold links for-->
<!-- ones that are cached-->
<a
href="#"
(click)="setPostId.emit(post.id)"
[style]="
queryClient.getQueryData(['post', post.id])
? {
fontWeight: 'bold',
color: 'green',
}
: {}
"
>{{ post.title }}</a
>
</p>
}
</div>
}
}
<div>
@if (postsQuery.isFetching()) {
Background Updating...
}
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Output,
inject,
} from '@angular/core'
import { QueryClient, injectQuery } from '@tanstack/angular-query-experimental'
import { lastValueFrom } from 'rxjs'
import { PostsService } from '../services/posts-service'

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'posts',
standalone: true,
templateUrl: './posts.component.html',
})
export class PostsComponent {
queryClient = inject(QueryClient)
#postsService = inject(PostsService)

@Output() setPostId = new EventEmitter<number>()

postsQuery = injectQuery(() => ({
queryKey: ['posts'],
queryFn: () => lastValueFrom(this.#postsService.allPosts$()),
}))
}
21 changes: 21 additions & 0 deletions examples/angular/basic-persister/src/app/services/posts-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { HttpClient } from '@angular/common/http'
import { Injectable, inject } from '@angular/core'

@Injectable({
providedIn: 'root',
})
export class PostsService {
#http = inject(HttpClient)

postById$ = (postId: number) =>
this.#http.get<Post>(`https://jsonplaceholder.typicode.com/posts/${postId}`)

allPosts$ = () =>
this.#http.get<Array<Post>>('https://jsonplaceholder.typicode.com/posts')
}

export interface Post {
id: number
title: string
body: string
}
Binary file added examples/angular/basic-persister/src/favicon.ico
Binary file not shown.
13 changes: 13 additions & 0 deletions examples/angular/basic-persister/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TanStack Query Angular basic persister 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>
<basic-example></basic-example>
</body>
</html>
7 changes: 7 additions & 0 deletions examples/angular/basic-persister/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { bootstrapApplication } from '@angular/platform-browser'
import { appConfig } from './app/app.config'
import { BasicExampleComponent } from './app/app.component'

bootstrapApplication(BasicExampleComponent, appConfig).catch((err) =>
console.error(err),
)
Loading
Loading