Skip to content

Commit

Permalink
feat(angular-query): add withDevtools and injectDevtoolsPanel
Browse files Browse the repository at this point in the history
  • Loading branch information
arnoud-dv authored Nov 7, 2024
1 parent 5ce9959 commit 2459701
Show file tree
Hide file tree
Showing 67 changed files with 1,620 additions and 154 deletions.
114 changes: 77 additions & 37 deletions docs/framework/angular/devtools.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,102 @@ id: devtools
title: Devtools
---

## Install and Import the Devtools
## Enable devtools

The devtools are a separate package that you need to install:
The devtools help you debug and inspect your queries and mutations. You can enable the devtools by adding `withDevtools` to `provideTanStackQuery`.

```bash
npm i @tanstack/angular-query-devtools-experimental
```

or
By default, the devtools are enabled when Angular [`isDevMode`](https://angular.dev/api/core/isDevMode) returns true. So you don't need to worry about excluding them during a production build. The core tools are lazily loaded and excluded from bundled code. In most cases, all you'll need to do is add `withDevtools()` to `provideTanStackQuery` without any additional configuration.

```bash
pnpm add @tanstack/angular-query-devtools-experimental
```ts
import {
QueryClient,
provideTanStackQuery,
withDevtools,
} from '@tanstack/angular-query-experimental'

export const appConfig: ApplicationConfig = {
providers: [provideTanStackQuery(new QueryClient(), withDevtools())],
}
```

or
## Configuring if devtools are loaded

```bash
yarn add @tanstack/angular-query-devtools-experimental
```
If you need more control over when devtools are loaded, you can use the `loadDevtools` option. This is particularly useful if you want to load devtools based on environment configurations. For instance, you might have a test environment running in production mode but still require devtools to be available.

When not setting the option or setting it to 'auto', the devtools will be loaded when Angular is in development mode.

or
```ts
provideTanStackQuery(new QueryClient(), withDevtools())

```bash
bun add @tanstack/angular-query-devtools-experimental
// which is equivalent to
provideTanStackQuery(
new QueryClient(),
withDevtools(() => ({ loadDevtools: 'auto' })),
)
```

You can import the devtools like this:
When setting the option to true, the devtools will be loaded in both development and production mode.

```ts
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
provideTanStackQuery(
new QueryClient(),
withDevtools(() => ({ loadDevtools: true })),
)
```

## Floating Mode
When setting the option to false, the devtools will not be loaded.

Floating Mode will mount the devtools as a fixed, floating element in your app and provide a toggle in the corner of the screen to show and hide the devtools. This toggle state will be stored and remembered in localStorage across reloads.

Place the following code as high in your Angular app as you can. The closer it is to the root of the page, the better it will work!
```ts
provideTanStackQuery(
new QueryClient(),
withDevtools(() => ({ loadDevtools: false })),
)
```

```angular-ts
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
import { Component } from '@angular/core';
The `withDevtools` options are returned from a callback function to support reactivity through signals. In the following example
a signal is created from a RxJS observable that listens for a keyboard shortcut. When the event is triggered, the devtools are lazily loaded.
Using this technique allows you to support on-demand loading of the devtools even in production mode, without including the full tools in the bundled code.

@Component({
selector: 'app-root',
standalone: true,
imports: [AngularQueryDevtools],
template: `
<angular-query-devtools initialIsOpen />
`,
})
```ts
@Injectable({ providedIn: 'root' })
class DevtoolsOptionsManager {
loadDevtools = toSignal(
fromEvent<KeyboardEvent>(document, 'keydown').pipe(
map(
(event): boolean =>
event.metaKey && event.ctrlKey && event.shiftKey && event.key === 'D',
),
scan((acc, curr) => acc || curr, false),
),
{
initialValue: false,
},
)
}

export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideTanStackQuery(
new QueryClient(),
withDevtools(() => ({
initialIsOpen: true,
loadDevtools: inject(DevtoolsOptionsManager).loadDevtools(),
})),
),
],
}
```

### Options

- `initialIsOpen: Boolean`
- Set this `true` if you want the dev tools to default to being open
Of these options `client`, `position`, `errorTypes`, `buttonPosition`, and `initialIsOpen` support reactivity through signals.

- `loadDevtools?: 'auto' | boolean`
- Defaults to `auto`: lazily loads devtools when in development mode. Skips loading in production mode.
- Use this to control if the devtools are loaded.
- `initialIsOpen?: Boolean`
- Set this to `true` if you want the tools to default to being open
- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "relative"`
- Defaults to `bottom-right`
- The position of the TanStack logo to open and close the devtools panel
Expand All @@ -67,8 +107,8 @@ import { Component } from '@angular/core';
- Defaults to `bottom`
- The position of the Angular Query devtools panel
- `client?: QueryClient`,
- Use this to use a custom QueryClient. Otherwise, the QueryClient provided through provideAngularQuery() will be injected.
- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
- Use this to use a custom QueryClient. Otherwise, the QueryClient provided through `provideTanStackQuery` will be injected.
- `errorTypes?: { name: string; initializer: (query: Query) => TError}[]`
- Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error.
- `styleNonce?: string`
- Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles.
Expand Down
2 changes: 1 addition & 1 deletion docs/framework/angular/guides/default-query-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const queryClient = new QueryClient({
})

bootstrapApplication(MyAppComponent, {
providers: [provideAngularQuery(queryClient)],
providers: [provideTanStackQuery(queryClient)],
})

export class PostsComponent {
Expand Down
2 changes: 1 addition & 1 deletion docs/framework/angular/guides/query-retries.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const queryClient = new QueryClient({
})

bootstrapApplication(AppComponent, {
providers: [provideAngularQuery(queryClient)],
providers: [provideTanStackQuery(queryClient)],
})
```

Expand Down
2 changes: 1 addition & 1 deletion docs/framework/angular/guides/window-focus-refetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ replace: { '@tanstack/react-query': '@tanstack/angular-query-experimental' }
```ts
bootstrapApplication(AppComponent, {
providers: [
provideAngularQuery(
provideTanStackQuery(
new QueryClient({
defaultOptions: {
queries: {
Expand Down
22 changes: 9 additions & 13 deletions docs/framework/angular/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ The `@tanstack/angular-query-experimental` package offers a 1st-class API for us

## Feedback welcome!

We are in the process of getting to a stable API for Angular Query. If you have any feedback, please contact us at the [TanStack Discord](https://tlinz.com/discord) server or [visit this discussion](https://github.com/TanStack/query/discussions/6293) on Github.
We are in the process of getting to a stable API for TanStack Query on Angular. If you have any feedback, please contact us at the [TanStack Discord](https://tlinz.com/discord) server or [visit this discussion](https://github.com/TanStack/query/discussions/6293) on Github.

## Supported Angular Versions

Angular Query is compatible with Angular v16 and higher.
TanStack Query is compatible with Angular v16 and higher.

TanStack Query (FKA React Query) is often described as the missing data-fetching library for web applications, but in more technical terms, it makes **fetching, caching, synchronizing and updating server state** in your web applications a breeze.

Expand Down Expand Up @@ -41,11 +41,11 @@ Once you grasp the nature of server state in your application, **even more chall

If you're not overwhelmed by that list, then that must mean that you've probably solved all of your server state problems already and deserve an award. However, if you are like a vast majority of people, you either have yet to tackle all or most of these challenges and we're only scratching the surface!

Angular Query is hands down one of the _best_ libraries for managing server state. It works amazingly well **out-of-the-box, with zero-config, and can be customized** to your liking as your application grows.
TanStack Query is hands down one of the _best_ libraries for managing server state. It works amazingly well **out-of-the-box, with zero-config, and can be customized** to your liking as your application grows.

Angular Query allows you to defeat and overcome the tricky challenges and hurdles of _server state_ and control your app data before it starts to control you.
TanStack Query allows you to defeat and overcome the tricky challenges and hurdles of _server state_ and control your app data before it starts to control you.

On a more technical note, Angular Query will likely:
On a more technical note, TanStack Query will likely:

- Help you remove **many** lines of complicated and misunderstood code from your application and replace with just a handful of lines of Angular Query logic.
- Make your application more maintainable and easier to build new features without worrying about wiring up new server state data sources
Expand All @@ -56,12 +56,11 @@ On a more technical note, Angular Query will likely:

## Enough talk, show me some code already!

In the example below, you can see Angular Query in its most basic and simple form being used to fetch the GitHub stats for the TanStack Query GitHub project itself:
In the example below, you can see TanStack Query in its most basic and simple form being used to fetch the GitHub stats for the TanStack Query GitHub project itself:

[Open in StackBlitz](https://stackblitz.com/github/TanStack/query/tree/main/examples/angular/simple)

```angular-ts
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { CommonModule } from '@angular/common'
Expand All @@ -86,10 +85,7 @@ import { lastValueFrom } from 'rxjs'
<strong>✨ {{ data.stargazers_count }}</strong>
<strong>🍴 {{ data.forks_count }}</strong>
}
<angular-query-devtools initialIsOpen />
`,
imports: [AngularQueryDevtools],
`
})
export class SimpleExampleComponent {
http = inject(HttpClient)
Expand All @@ -103,7 +99,7 @@ export class SimpleExampleComponent {
}))
}
type Response = {
interface Response {
name: string
description: string
subscribers_count: number
Expand All @@ -114,4 +110,4 @@ type Response = {

## You talked me into it, so what now?

- Learn Angular Query at your own pace with our amazingly thorough [Walkthrough Guide](../installation) and [API Reference](../reference/functions/injectquery)
- Learn TanStack Query at your own pace with our amazingly thorough [Walkthrough Guide](../installation) and [API Reference](../reference/functions/injectquery)
8 changes: 4 additions & 4 deletions docs/framework/angular/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ If you're looking for a fully functioning example, please have a look at our [ba
```ts
import { provideHttpClient } from '@angular/common/http'
import {
provideAngularQuery,
provideTanStackQuery,
QueryClient,
} from '@tanstack/angular-query-experimental'

bootstrapApplication(AppComponent, {
providers: [provideHttpClient(), provideAngularQuery(new QueryClient())],
providers: [provideHttpClient(), provideTanStackQuery(new QueryClient())],
})
```

Expand All @@ -28,14 +28,14 @@ or in a NgModule-based app
```ts
import { provideHttpClient } from '@angular/common/http'
import {
provideAngularQuery,
provideTanStackQuery,
QueryClient,
} from '@tanstack/angular-query-experimental'

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [provideAngularQuery(new QueryClient())],
providers: [provideTanStackQuery(new QueryClient())],
bootstrap: [AppComponent],
})
export class AppModule {}
Expand Down
1 change: 0 additions & 1 deletion examples/angular/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"@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.20",
"typescript": "5.3.3"
}
}
1 change: 0 additions & 1 deletion examples/angular/basic/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
sequences)
</strong>
</p>
<angular-query-devtools initialIsOpen />
@if (postId() > -1) {
<post [postId]="postId()" (setPostId)="postId.set($event)"></post>
} @else {
Expand Down
3 changes: 1 addition & 2 deletions examples/angular/basic/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
import { ChangeDetectionStrategy, Component, signal } from '@angular/core'
import { PostComponent } from './components/post.component'
import { PostsComponent } from './components/posts.component'
Expand All @@ -8,7 +7,7 @@ import { PostsComponent } from './components/posts.component'
selector: 'basic-example',
standalone: true,
templateUrl: './app.component.html',
imports: [AngularQueryDevtools, PostComponent, PostsComponent],
imports: [PostComponent, PostsComponent],
})
export class BasicExampleComponent {
postId = signal(-1)
Expand Down
8 changes: 5 additions & 3 deletions examples/angular/basic/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { provideHttpClient, withFetch } from '@angular/common/http'
import {
QueryClient,
provideAngularQuery,
provideTanStackQuery,
withDevtools,
} from '@tanstack/angular-query-experimental'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
providers: [
provideAngularQuery(
provideHttpClient(withFetch()),
provideTanStackQuery(
new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 60 * 60 * 24, // 24 hours
},
},
}),
withDevtools(),
),
provideHttpClient(withFetch()),
],
}
6 changes: 6 additions & 0 deletions examples/angular/devtools-panel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# TanStack Query Angular devtools panel 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`
Loading

0 comments on commit 2459701

Please sign in to comment.