Skip to content

Commit

Permalink
feat: experimental angular query adapter (#6195)
Browse files Browse the repository at this point in the history
* feat(angular-query): add Angular Query

* feat(angular-query): integration test

* fix(angular-query): PR feedback on QueryClientService injection

* fix(angular-query): PR feedback

* chore(angular-query): update unit tests

* feat(angular-query): custom inject functions

* feat(angular-query): docs

* fix(angular-query): replace React context mention with Angular injector

* fix(angular-query): re-add missing angular-query-experimental package config

* feat: updated angular version

* feat: code improvements, DX improvements, fixed small doc example to use http client,

* Update docs/angular/overview.md

* version fixes

* feat: use proxy object to create single signals (computed) for query fields instead of query itself being a signal and improved types

* fix: docs

* Update packages/angular-query-experimental/src/query-proxy.ts

Co-authored-by: Chau Tran <[email protected]>

* Update packages/angular-query-experimental/src/query-proxy.ts

Co-authored-by: Chau Tran <[email protected]>

* fix: add missing import

* revert: use helper method for injectQueryClient

* Add Angular-CLI apps for testing

* fix: useValue instead of useFactory

* fix(angular-query): examples

* chore(angular-query): remove build script from angular 17 integration

* fix(angular-query): add sandbox config

* build working for angular-query-devtools-experimental

* fix(angular-query): improve development workflow

* fix(angular-query): downgrade vitest

* fix(angular-query): eslint and unit test typing fix

* fix(angular-query): test:ci fixes

* fix(angular-query): relative workspace path to build dir

* fix(angular-query): configure workspaces for top directories only

* chore(angular-query): remove dead code found by Knip

---------

Co-authored-by: Enea Jahollari <[email protected]>
Co-authored-by: Chau Tran <[email protected]>
Co-authored-by: Tomasz Ducin <[email protected]>
Co-authored-by: Tomasz Ducin <[email protected]>
Co-authored-by: Dominik Dorfmeister <[email protected]>
  • Loading branch information
6 people authored Dec 1, 2023
1 parent af0ff9a commit 46034aa
Show file tree
Hide file tree
Showing 117 changed files with 7,188 additions and 773 deletions.
3 changes: 2 additions & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
"installCommand": "install:csb",
"buildCommand": "build:all",
"sandboxes": [
"/examples/angular/basic",
"/examples/react/basic-typescript",
"/examples/solid/basic-typescript",
"/examples/svelte/basic",
"/examples/vue/basic"
],
"packages": ["packages/**"],
"packages": ["packages/**", "!packages/angular*", "packages/angular-query-devtools-experimental/build", "packages/angular-query-experimental/build"],
"node": "18"
}
55 changes: 55 additions & 0 deletions docs/angular/devtools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
id: devtools
title: Devtools
---

## Install and Import the Devtools

The devtools are a separate package that you need to install:

```bash
$ npm i @tanstack/angular-query-devtools-experimental
# or
$ pnpm add @tanstack/angular-query-devtools-experimental
# or
$ yarn add @tanstack/angular-query-devtools-experimental
```

You can import the devtools like this:

```typescript
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental'
```

## Floating Mode

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!

```typescript
import { AngularQueryDevtoolsComponent } from '@tanstack/angular-query-devtools-experimental'
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
standalone: true,
imports: [AngularQueryDevtoolsComponent],
template: `
<angular-query-devtools initialIsOpen />
`,
})
```

### Options

- `initialIsOpen: Boolean`
- Set this `true` if you want the dev tools to default to being open
- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"`
- Defaults to `bottom-left`
- The position of the TanStack logo to open and close the devtools panel
- `position?: "top" | "bottom" | "left" | "right"`
- 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.
20 changes: 20 additions & 0 deletions docs/angular/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
id: installation
title: Installation
---

> VERY IMPORTANT: This library is currently in an experimental stage. This means that breaking changes will happen in minor AND patch releases. Use at your own risk. If you choose to rely on this in production in an experimental stage, please lock your version to a patch-level version to avoid unexpected breakages.
### NPM

Angular Query is compatible with Angular v16+.

```bash
$ npm i @tanstack/angular-query-experimental
# or
$ pnpm add @tanstack/angular-query-experimental
# or
$ yarn add @tanstack/angular-query-experimental
```

> Wanna give it a spin before you download? Try out the [simple](../examples/angular/simple) or [basic](../examples/angular/basic) examples!
68 changes: 68 additions & 0 deletions docs/angular/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
id: overview
title: Overview
---

> VERY IMPORTANT: This library is currently in an experimental stage. This means that breaking changes will happen in minor AND patch releases. Use at your own risk. If you choose to rely on this in production in an experimental stage, please lock your version to a patch-level version to avoid unexpected breakages.
The `@tanstack/angular-query-experimental` package offers a 1st-class API for using TanStack Query via Angular.

## Feedback very 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.

## Versions of Angular supported
The adapter works with signals, which means it only supports Angular 16+

## Example

```typescript
import { AngularQueryDevtoolsComponent } from '@tanstack/angular-query-devtools-experimental'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { CommonModule } from '@angular/common'
import { injectQuery } from '@tanstack/angular-query-experimental'
import { lastValueFrom } from 'rxjs'

type Response = {
name: string
description: string
subscribers_count: number
stargazers_count: number
forks_count: number
}

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'simple-example',
standalone: true,
template: `
@if (query.isPending()) {
Loading...
}
@if (query.error()) {
An error has occurred: {{ query.error().message }}
}
@if (query.data(); as data) {
<h1>{{ data.name }}</h1>
<p>{{ data.description }}</p>
<strong>👀 {{ data.subscribers_count }}</strong>
<strong>✨ {{ data.stargazers_count }}</strong>
<strong>🍴 {{ data.forks_count }}</strong>
}
<angular-query-devtools initialIsOpen />
`,
imports: [AngularQueryDevtoolsComponent],
})
export class SimpleExampleComponent {
http = inject(HttpClient)

query = injectQuery(() => ({
queryKey: ['repoData'],
queryFn: () =>
lastValueFrom(
this.http.get<Response>('https://api.github.com/repos/tannerlinsley/react-query')
),
}))
}
```
72 changes: 72 additions & 0 deletions docs/angular/quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
id: quick-start
title: Quick Start
---

> VERY IMPORTANT: This library is currently in an experimental stage. This means that breaking changes will happen in minor AND patch releases. Use at your own risk. If you choose to rely on this in production in an experimental stage, please lock your version to a patch-level version to avoid unexpected breakages.
[//]: # 'Example'

If you're looking for a fully functioning example, please have a look at our [basic codesandbox example](../examples/angular/basic)

### Provide the client to your App

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

### Component with query and mutation

```typescript
import {
injectMutation,
injectQuery,
injectQueryClient
} from '@tanstack/angular-query-experimental'
import { getTodos, postTodo } from '../my-api'

@Component({
standalone: true,
template: `
<div>
<ul>
@for (todo of query().data) {
<li>{{ todo.title }}</li>
}
</ul>
<button (click)="onAddTodo()">Add Todo</button>
</div>
`,
})
export class TodosComponent {
queryClient = injectQueryClient()

query = injectQuery(() => ({
queryKey: ['todos'],
queryFn: getTodos
}))

mutation = injectMutation((client) => ({
mutationFn: postTodo,
onSuccess: () => {
// Invalidate and refetch by using the client directly
client.invalidateQueries({ queryKey: ['todos'] })

// OR use the queryClient that is injected into the component
this.queryClient.invalidateQueries({ queryKey: ['todos'] })
}
}))

onAddTodo() {
this.mutation().mutate({
id: Date.now(),
title: 'Do Laundry',
})
}
}
```

[//]: # 'Example'
24 changes: 24 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,30 @@
]
}
]
},
{"framework": "angular", "menuItems":[
{
"label": "Getting Started",
"children": [
{
"label": "Overview",
"to": "angular/overview"
},
{
"label": "Installation",
"to": "angular/installation"
},
{
"label": "Quick Start",
"to": "angular/quick-start"
},
{
"label": "Devtools",
"to": "angular/devtools"
}
]
}
]
}
],
"users": [
Expand Down
11 changes: 11 additions & 0 deletions examples/angular/basic/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @ts-check

/** @type {import('eslint').Linter.Config} */
const config = {
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
},
}

module.exports = config
6 changes: 6 additions & 0 deletions examples/angular/basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Basic example

To run this example:

- `npm install` or `yarn` or `pnpm i`
- `npm run dev` or `yarn dev` or `pnpm dev`
12 changes: 12 additions & 0 deletions examples/angular/basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Angular Query basic example</title>
</head>
<body>
<basic-example />
<script type="module" src="src/index.ts"></script>
</body>
</html>
30 changes: 30 additions & 0 deletions examples/angular/basic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@tanstack/query-example-angular-basic",
"private": true,
"type": "module",
"version": "0.0.0",
"description": "",
"scripts": {
"start": "vite",
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"license": "MIT",
"dependencies": {
"@angular/common": "^17.0.2",
"@angular/compiler": "^17.0.2",
"@angular/core": "^17.0.2",
"@angular/language-service": "^17.0.2",
"@angular/platform-browser": "^17.0.2",
"@tanstack/angular-query-experimental": "^5.0.0",
"@tanstack/angular-query-devtools-experimental": "^5.0.0",
"axios": "^1.5.1",
"rxjs": "^7.8.1",
"zone.js": "^0.14.2"
},
"devDependencies": {
"typescript": "^5.2.2",
"vite": "^4.5.0"
}
}
13 changes: 13 additions & 0 deletions examples/angular/basic/public/emblem-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions examples/angular/basic/sandbox.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"container": {
"node": "18"
}
}
Loading

0 comments on commit 46034aa

Please sign in to comment.