Skip to content

Commit ef9c853

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feature/angular-stable
2 parents 589b9d1 + dcfc100 commit ef9c853

File tree

203 files changed

+4602
-4989
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

203 files changed

+4602
-4989
lines changed

.github/workflows/autofix.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ jobs:
2424
- name: Fix formatting
2525
run: pnpm prettier:write
2626
- name: Apply fixes
27-
uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
27+
uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef
2828
with:
2929
commit-message: 'ci: apply automated fixes'

CONTRIBUTING.md

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,63 @@ If you have been assigned to fix an issue or develop a new feature, please follo
5252
- Git stage your required changes and commit (see below commit guidelines).
5353
- Submit PR for review.
5454

55+
### Editing the docs locally and previewing the changes
56+
57+
The documentations for all the TanStack projects are hosted on [tanstack.com](https://tanstack.com), which is a TanStack Start application (https://github.com/TanStack/tanstack.com). You need to run this app locally to preview your changes in the `TanStack/query` docs.
58+
59+
> [!NOTE]
60+
> The website fetches the doc pages from GitHub in production, and searches for them at `../query/docs` in development. Your local clone of `TanStack/query` needs to be in the same directory as the local clone of `TansStack/tanstack.com`.
61+
62+
You can follow these steps to set up the docs for local development:
63+
64+
1. Make a new directory called `tanstack`.
65+
66+
```sh
67+
mkdir tanstack
68+
```
69+
70+
2. Enter that directory and clone the [`TanStack/query`](https://github.com/TanStack/query) and [`TanStack/tanstack.com`](https://github.com/TanStack/tanstack.com) repos.
71+
72+
```sh
73+
cd tanstack
74+
git clone git@github.com:TanStack/query.git
75+
# We probably don't need all the branches and commit history
76+
# from the `tanstack.com` repo, so let's just create a shallow
77+
# clone of the latest version of the `main` branch.
78+
# Read more about shallow clones here:
79+
# https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/#user-content-shallow-clones
80+
git clone git@github.com:TanStack/tanstack.com.git --depth=1 --single-branch --branch=main
81+
```
82+
83+
> [!NOTE]
84+
> Your `tanstack` directory should look like this:
85+
>
86+
> ```
87+
> tanstack/
88+
> |
89+
> +-- query/ (<-- this directory cannot be called anything else!)
90+
> |
91+
> +-- tanstack.com/
92+
> ```
93+
94+
3. Enter the `tanstack/tanstack.com` directory, install the dependencies and run the app in dev mode:
95+
96+
```sh
97+
cd tanstack.com
98+
pnpm i
99+
# The app will run on https://localhost:3000 by default
100+
pnpm dev
101+
```
102+
103+
4. Now you can visit http://localhost:3000/query/latest/docs/overview in the browser and see the changes you make in `tanstack/query/docs` there.
104+
105+
> [!WARNING]
106+
> You will need to update the `docs/config.json` file (in `TanStack/query`) if you add a new documentation page!
107+
108+
You can see the whole process in the screen capture below:
109+
110+
https://github.com/fulopkovacs/form/assets/43729152/9d35a3c3-8153-4e74-9cb2-af275f7a269b
111+
55112
### Running examples
56113

57114
- Make sure you've installed the dependencies in the repo's root directory.
@@ -72,10 +129,6 @@ If you have been assigned to fix an issue or develop a new feature, please follo
72129
pnpm run dev
73130
```
74131

75-
#### Note on `examples/react-native`
76-
77-
React Native example requires Expo to work. Please follow the instructions from example's README.md file to learn more.
78-
79132
#### Note on standalone execution
80133

81134
If you want to run an example without installing dependencies for the whole repo, just follow instructions from the example's README.md file. It will be then run against the latest TanStack Query release.

docs/config.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@
9999
"label": "TypeScript",
100100
"to": "framework/vue/typescript"
101101
},
102+
{
103+
"label": "Reactivity",
104+
"to": "framework/vue/reactivity"
105+
},
102106
{
103107
"label": "GraphQL",
104108
"to": "framework/vue/graphql"
@@ -116,6 +120,10 @@
116120
"label": "Installation",
117121
"to": "framework/svelte/installation"
118122
},
123+
{
124+
"label": "Devtools",
125+
"to": "framework/svelte/devtools"
126+
},
119127
{
120128
"label": "SSR & SvelteKit",
121129
"to": "framework/svelte/ssr"
@@ -141,6 +149,10 @@
141149
"label": "Quick Start",
142150
"to": "framework/angular/quick-start"
143151
},
152+
{
153+
"label": "Angular HttpClient and other data fetching clients",
154+
"to": "framework/angular/angular-httpclient-and-other-data-fetching-clients"
155+
},
144156
{
145157
"label": "Devtools",
146158
"to": "framework/angular/devtools"
@@ -1050,6 +1062,10 @@
10501062
"label": "Auto Refetching / Polling / Realtime",
10511063
"to": "framework/angular/examples/auto-refetching"
10521064
},
1065+
{
1066+
"label": "Optimistic Updates",
1067+
"to": "framework/angular/examples/optimistic-updates"
1068+
},
10531069
{
10541070
"label": "Pagination",
10551071
"to": "framework/angular/examples/pagination"

docs/eslint/eslint-plugin-query.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ Alternatively, add `@tanstack/query` to the plugins section, and configure the r
9393

9494
## Rules
9595

96-
- [@tanstack/query/exhaustive-deps](../exhaustive-deps)
97-
- [@tanstack/query/no-rest-destructuring](../no-rest-destructuring)
98-
- [@tanstack/query/stable-query-client](../stable-query-client)
99-
- [@tanstack/query/no-unstable-deps](../no-unstable-deps)
100-
- [@tanstack/query/infinite-query-property-order](../infinite-query-property-order)
96+
- [@tanstack/query/exhaustive-deps](./exhaustive-deps)
97+
- [@tanstack/query/no-rest-destructuring](./no-rest-destructuring)
98+
- [@tanstack/query/stable-query-client](./stable-query-client)
99+
- [@tanstack/query/no-unstable-deps](./no-unstable-deps)
100+
- [@tanstack/query/infinite-query-property-order](./infinite-query-property-order)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
id: Angular-HttpClient-and-other-data-fetching-clients
3+
title: Angular HttpClient and other data fetching clients
4+
---
5+
6+
Because TanStack Query's fetching mechanisms are agnostically built on Promises, you can use literally any asynchronous data fetching client, including the browser native `fetch` API, `graphql-request`, and more.
7+
8+
## Using Angular's `HttpClient` for data fetching
9+
10+
`HttpClient` is a powerful and integrated part of Angular, which gives the following benefits:
11+
12+
- Mock responses in unit tests using [provideHttpClientTesting](https://angular.dev/guide/http/testing).
13+
- [Interceptors](https://angular.dev/guide/http/interceptors) can be used for a wide range of functionality including adding authentication headers, performing logging, etc. While some data fetching libraries have their own interceptor system, `HttpClient` interceptors are integrated with Angular's dependency injection system.
14+
- `HttpClient` automatically informs [`PendingTasks`](https://angular.dev/api/core/PendingTasks#), which enables Angular to be aware of pending requests. Unit tests and SSR can use the resulting application _stableness_ information to wait for pending requests to finish. This makes unit testing much easier for [Zoneless](https://angular.dev/guide/experimental/zoneless) applications.
15+
- When using SSR, `HttpClient` will [cache requests](https://angular.dev/guide/ssr#caching-data-when-using-HttpClient) performed on the server. This will prevent unneeded requests on the client. `HttpClient` SSR caching works out of the box. TanStack Query has its own hydration functionality which may be more powerful but requires some setup. Which one fits your needs best depends on your use case.
16+
17+
### Using observables in `queryFn`
18+
19+
As TanStack Query is a promise based library, observables from `HttpClient` need to be converted to promises. This can be done with the `lastValueFrom` or `firstValueFrom` functions from `rxjs`.
20+
21+
```ts
22+
@Component({
23+
// ...
24+
})
25+
class ExampleComponent {
26+
private readonly http = inject(HttpClient)
27+
28+
readonly query = injectQuery(() => ({
29+
queryKey: ['repoData'],
30+
queryFn: () =>
31+
lastValueFrom(
32+
this.http.get('https://api.github.com/repos/tanstack/query'),
33+
),
34+
}))
35+
}
36+
```
37+
38+
> Since Angular is moving towards RxJS as an optional dependency, it's expected that `HttpClient` will also support promises in the future.
39+
>
40+
> Support for observables in TanStack Query for Angular is planned.
41+
42+
## Comparison table
43+
44+
| Data fetching client | Pros | Cons |
45+
| --------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------- |
46+
| **Angular HttpClient** | Featureful and very well integrated with Angular. | Observables need to be converted to Promises. |
47+
| **Fetch** | Browser native API, so adds nothing to bundle size. | Barebones API which lacks many features. |
48+
| **Specialized libraries such as `graphql-request`** | Specialized features for specific use cases. | If it's not an Angular library it won't integrate well with the framework. |

docs/framework/angular/guides/background-fetching-indicators.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,23 @@ ref: docs/framework/react/guides/background-fetching-indicators.md
88

99
```angular-ts
1010
@Component({
11-
selector: 'posts',
11+
selector: 'todos',
1212
template: `
13-
@switch (query.status()) {
14-
@case ('pending') {
15-
Loading...
13+
@if (todosQuery.isPending()) {
14+
Loading...
15+
} @else if (todosQuery.isError()) {
16+
An error has occurred: {{ todosQuery.error().message }}
17+
} @else if (todosQuery.isSuccess()) {
18+
@if (todosQuery.isFetching()) {
19+
Refreshing...
1620
}
17-
@case ('error') {
18-
An error has occurred: {{ query.error()?.message }}
19-
}
20-
@default {
21-
@if (query.isFetching()) {
22-
Refreshing...
23-
}
24-
@for (todo of query.data()) {
25-
<todo [todo]="todo" />
26-
}
21+
@for (todos of todosQuery.data(); track todo.id) {
22+
<todo [todo]="todo" />
2723
}
2824
}
2925
`,
3026
})
31-
export class TodosComponent {
27+
class TodosComponent {
3228
todosQuery = injectQuery(() => ({
3329
queryKey: ['todos'],
3430
queryFn: fetchTodos,

docs/framework/angular/guides/disabling-queries.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ export class TodosComponent {
7070
[//]: # 'Example3'
7171

7272
```angular-ts
73+
import { skipToken, injectQuery } from '@tanstack/query-angular'
74+
7375
@Component({
7476
selector: 'todos',
7577
template: `

docs/framework/angular/guides/queries.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ replace:
1010
'custom hooks': 'services',
1111
'the `useQuery` hook': '`injectQuery`',
1212
'`useQuery`': '`injectQuery`',
13+
"TypeScript will also narrow the type of data correctly if you've checked for pending and error before accessing it.": 'TypeScript will only narrow the type when checking boolean signals such as `isPending` and `isError`.',
1314
}
1415
---
1516

docs/framework/angular/guides/query-options.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,28 @@ export class QueriesService {
3131

3232
// usage:
3333

34+
postId = input.required({
35+
transform: numberAttribute,
36+
})
3437
queries = inject(QueriesService)
3538

36-
injectQuery(this.queries.post(1))
37-
injectQueries({
38-
queries: [this.queries.post(1), this.queries.post(2)],
39-
})
39+
postQuery = injectQuery(() => this.queries.post(this.postId()))
40+
4041
queryClient.prefetchQuery(this.queries.post(23))
41-
queryClient.setQueryData(this.queries.post(42).queryKey, newGroups)
42+
queryClient.setQueryData(this.queries.post(42).queryKey, newPost)
4243
```
4344

4445
[//]: # 'Example1'
46+
[//]: # 'Example2'
47+
48+
```ts
49+
// Type inference still works, so query.data will be the return type of select instead of queryFn
50+
queries = inject(QueriesService)
51+
52+
query = injectQuery(() => ({
53+
...groupOptions(1),
54+
select: (data) => data.title,
55+
}))
56+
```
57+
58+
[//]: # 'Example2'

docs/framework/angular/guides/window-focus-refetching.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ replace: { '@tanstack/react-query': '@tanstack/angular-query' }
88
[//]: # 'Example'
99

1010
```ts
11-
bootstrapApplication(AppComponent, {
11+
export const appConfig: ApplicationConfig = {
1212
providers: [
1313
provideTanStackQuery(
1414
new QueryClient({
@@ -20,7 +20,7 @@ bootstrapApplication(AppComponent, {
2020
}),
2121
),
2222
],
23-
})
23+
}
2424
```
2525

2626
[//]: # 'Example'

0 commit comments

Comments
 (0)