{"id":15657727,"url":"https://github.com/isaacplmann/ngrx-query","last_synced_at":"2025-05-05T16:40:33.584Z","repository":{"id":68879782,"uuid":"84457794","full_name":"isaacplmann/ngrx-query","owner":"isaacplmann","description":"ngrx-query is a library for querying and managing network state in Angular (2+) applications that use ngrx","archived":false,"fork":false,"pushed_at":"2018-10-22T18:20:10.000Z","size":6036,"stargazers_count":23,"open_issues_count":3,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-30T22:25:13.563Z","etag":null,"topics":["angular","network","ngrx","optimistic-updates","redux","redux-query","retry"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/isaacplmann.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-09T15:30:50.000Z","updated_at":"2023-04-20T14:15:00.000Z","dependencies_parsed_at":"2023-03-07T01:45:14.647Z","dependency_job_id":null,"html_url":"https://github.com/isaacplmann/ngrx-query","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isaacplmann%2Fngrx-query","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isaacplmann%2Fngrx-query/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isaacplmann%2Fngrx-query/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isaacplmann%2Fngrx-query/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/isaacplmann","download_url":"https://codeload.github.com/isaacplmann/ngrx-query/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252534999,"owners_count":21763874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","network","ngrx","optimistic-updates","redux","redux-query","retry"],"created_at":"2024-10-03T13:09:25.049Z","updated_at":"2025-05-05T16:40:33.560Z","avatar_url":"https://github.com/isaacplmann.png","language":"TypeScript","readme":"# ngrx-query\n\n`ngrx-query` is a library for querying and managing network state in [Angular (2+)](https://angular.io) applications that use [ngrx](https://github.com/ngrx/store).  It is a port of the [redux-query](https://github.com/amplitude/redux-query) library - many thanks to `redux-query` for coming up with a very useful library.  For an in-depth explanation of what problems `redux-query` (and, by extension, `ngrx-query`) solve, read [Introducing redux-query](https://amplitude.engineering/introducing-redux-query-7734e7215b3b).\n\nCheck out the [demo](https://isaacplmann.github.io/ngrx-query/) to see the final outcome, but the real power of this library is the reduction of boilerplate code.\n\nWith `ngrx-query` you can:\n\n- Declare your network dependencies right next to your Angular components. Data is requested automatically when components mount. When components update and unmount, ~in-flight requests are automatically cancelled~ the subscription is automatically unsubscribed. TODO: check if in-flight requests really are cancelled.\n- Trigger server-side changes (mutations) by dispatching regular Redux actions.\n- Have a consistent, minimal-boilerplate interface for all network-related state.\n- Transform and normalize data to avoid duplicate state.\n- Perform optimistic updates.\n- Use with other ngrx libraries like [@ngrx/effects](https://github.com/ngrx/effects).\n- Debug network state and actions with Redux dev tools like [ngrx-store-logger](https://github.com/btroncone/ngrx-store-logger) or the [Redux Devtools browser extension](https://github.com/zalmoxisus/redux-devtools-extension).\n\n## Getting Started\n\nInstall `ngrx-query` via npm:\n\n```\n$ npm install --save ngrx-query\n```\n\nAdd the `entitiesReducer` and `queriesReducer` to your combined reducer.\n\nImport the `NgrxQueryModule.forRoot()` in your root `AppModule`.\n\nFor example:\n\n```ts\n@NgModule({\n  // ...\n  imports: [\n    // ...\n    StoreModule.forRoot({\n      entities: entitiesReducer,\n      queries: queriesReducer,\n    }),\n    NgrxQueryModule.forRoot(),\n  ],\n})\nexport class AppModule {}\n```\n\n## Dependencies\n\nAll dependencies are listed in [`package.json`](./package.json). @angular/core, @angular/http, @ngrx/store (^4.0.2) and @ngrx/effects (^4.0.2) are peer dependencies. HTTP requests are made using `@angular/http`'s Http service.\n\n## Global config\n\n`NgrxQueryModule.forRoot()` optionally accepts an `NgrxQueryConfig` object.\n\n```ts\n// functions must be exported and named in order build with AoT\nexport function queriesSelector(state) {\n  return state.my.path.to.queries;\n}\nexport function entitiesSelector(state) {\n  return state.my.path.to.entities;\n}\n\n@NgModule({\n  // ...\n  imports: [\n    // ...\n    NgrxQueryModule.forRoot({\n      // Determines where to locate the queries in the store\n      // Must match the location of the queriesReducer\n      // default: (state) =\u003e state.queries\n      queriesSelector: queriesSelector,\n\n      // Determines where to locate the entities in the store\n      // Must match the location of the entitiesReducer\n      // default: (state) =\u003e state.entities\n      entitiesSelector: entitiesSelector,\n\n      // Determines how much to delay between retry attempts\n      // default: { maxAttemps: 5, maxDuration: 5000, minDuration: 300 }\n      backoff: {\n        maxAttempts: 3, // number of attempts\n        maxDuration: 1000, // ms\n        minDuration: 300, // ms\n      },\n\n      // Determines which status codes on a GET response will trigger a retry\n      // default: [\n      //   UNKNOWN = 0, // normally means a failed connection\n      //   REQUEST_TIMEOUT = 408, // client took too long\n      //   TOO_MANY_REQUESTS = 429, // hopefully backoff stops this getting worse\n      //   SERVICE_UNAVAILABLE = 503,\n      //   GATEWAY_TIMEOUT = 504,\n      // ]\n      retryableStatusCodes: [ 408 ],\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n## Usage and API\n\n### Requests and mutations\n\nThere are two types of queries with `ngrx-query`: \"requests\" and \"mutations\". Requests are for reading values from HTTP endpoints. Mutations are for HTTP endpoints that change network state – the \"C\", \"U\", and \"D\" in \"CRUD\".\n\nRequests can be triggered from the `nqConnect` attribute directive, the `ConnectService` or a `requestAsync` action. Mutations are triggered by the `ConnectService` or by dispatching a `mutateAsync` action.\n\nBy default, requests are GETs and mutations are POSTS.\n\n### Query configs\n\nQuery configs are objects used to describe how ngrx-query should handle the request or mutation. Query config options differ slightly between requests and mutations\n\n#### Request query config options\n\n| Name | Type | Required? | Description |\n|:---|:---|:---:|:---|\n| `url` | string | yes | The URL for the HTTP request. |\n| `transform` | function |  | Function that transforms the response data to an entities object where keys are entity IDs and values are entity data. Can be used to normalize data. |\n| `update` | object | yes | Object where keys are entity IDs and values are update functions. |\n| `body` | object |  | The request body. |\n| `force` | boolean |  | Perform the request even if we've already successfully requested it. |\n| `queryKey` | string |  | The identifier used to identify the query metadata in the `queries` reducer. If unprovided, the `url` and `body` fields are serialized to generate the query key. |\n| `meta` | object |  | Various metadata for the query. Can be used to update other reducers when queries succeed or fail. |\n| `options` | object |  | Options for the request. Set `options.method` to change the HTTP method, `options.headers` to set any headers and `options.credentials = 'include'` for CORS. |\n\n#### Mutation query config options\n\n| Name | Type | Required? | Description |\n|:---|:---|:---:|:---|\n| `url` | string | yes | The URL for the HTTP request. |\n| `transform` | function |  | Function that transforms the response data to an entities object where keys are entity IDs and values are entity data. Can be used to normalize data. |\n| `update` | object | yes | Object where keys are entity IDs and values are update functions. |\n| `optimisticUpdate` | object |  | Object where keys are entity IDs and values are functions that provide the current entity value. The return values are used to update the `entities` store until the mutation finishes. |\n| `body` | object |  | The HTTP request body. |\n| `queryKey` | string |  | The identifier used to identify the query metadata in the `queries` reducer. If unprovided, the `url` and `body` fields are serialized to generate the query key. |\n| `options` | object |  | Options for the request. Set `options.method` to change the HTTP method, `options.headers` to set any headers and `options.credentials = 'include'` for CORS. |\n\n### `transform` functions\n\n`transform` functions let you process and normalize response data before it is passed to the `update` step. They have the following signature:\n\n```javascript\n(responseJson: ?Object, responseText: string) =\u003e { [key: string]: any }\n```\n\nIf your data is normalized on the server, you may not need to use this function.\n\n### `update` functions\n\n`update` functions are responsible for reconciling response data with the existing `entities` reducer data for the given entity ID. They have the following signature:\n\n```javascript\n(prevValue: any, transformedValue: any) =\u003e any\n```\n\nThe `prevValue` is whatever value is selected from the `entities` reducer for the respective entity ID. The returned value from this function will become the new value for the entity ID in the `entities` reducer.\n\n### `optimisticUpdate` functions\n\n`optimisticUpdate` functions are just like update functions except they only pass the `prevValue`:\n\n```javascript\n(prevValue: any) =\u003e any\n```\n\n### `ngConnect`\n\nUse the `nqConnect` attribute directive to declare network dependencies for an Angular component. `nqConnect` takes a request query config object. Example usage:\n\n```ts\n// TODO\n```\n\n`connectRequest` passes an extra prop to the child component: `forceRequest`. Calling this function will cause the request(s) to be made again. This may be useful for polling or creating an interface to trigger refreshes.\n\n### `mutateAsync`\n\nDispatch `mutateAsync` Redux actions to trigger mutations. `mutateAsync` takes a mutation query config as its only argument. Example usage with an Angular component:\n\n```ts\n// TODO\n```\n\n### `requestAsync`\n\nSimilarly to how mutations are triggered by dispatching `mutateAsync` actions, you can trigger requests by dispatching `requestAsync` actions with a request query config.\n\n## Example\n\nA simple example is included. To run it, simply:\n\n```sh\n$ npm install\n$ npm run start\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisaacplmann%2Fngrx-query","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fisaacplmann%2Fngrx-query","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisaacplmann%2Fngrx-query/lists"}