-
Notifications
You must be signed in to change notification settings - Fork 1.1k
docs: adding working with data pages #4970
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
Changes from all commits
6902eef
edc080a
57b487a
a640b21
e32ef98
b9084fd
0d537d2
eb722d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| --- | ||
| title: 'Fields filter' | ||
| lang: en | ||
| keywords: LoopBack 4.0, LoopBack 4, fields | ||
| sidebar: lb4_sidebar | ||
| permalink: /doc/en/lb4/Fields-filter.html | ||
| --- | ||
|
|
||
| A _fields_ filter specifies properties (fields) to include or exclude from the | ||
| results. | ||
|
|
||
| ### Node.js API | ||
|
|
||
| {% include content/angular-methods-caveat.html lang=page.lang %} | ||
|
|
||
| <pre> | ||
| { fields: {<i>propertyName</i>: <true|false>, <i>propertyName</i>: <true|false>, ... } } | ||
| </pre> | ||
|
|
||
| Where: | ||
|
|
||
| - _propertyName_ is the name of the property (field) to include or exclude. | ||
| - `<true|false>` signifies either `true` or `false` Boolean literal. Use `true` | ||
| to include the property or `false` to exclude it from results. | ||
|
|
||
| By default, queries return all model properties in results. However, if you | ||
| specify at least one fields filter with a value of `true`, then by default the | ||
| query will include **only** those you specifically include with filters. | ||
|
|
||
| ### REST API | ||
|
|
||
| {% include warning.html content=" | ||
| As a known bug, the option `<false>` does not work for url for now. Please include the properties you need or use the [stringified JSON format](Querying-data.html#using-stringified-json-in-rest-queries) to meet your requirement. The bug is tracked in the GH issue [#4992](https://github.com/strongloop/loopback-next/issues/4992)" %} | ||
|
|
||
| <pre> | ||
| filter[fields][<i>propertyName</i>]=<true>&filter[fields][<i>propertyName</i>]=<true>... | ||
| </pre> | ||
|
|
||
| Note that to include more than one field in REST, use multiple filters. | ||
|
|
||
| Check out the usage of | ||
| [stringified JSON format](Querying-data.html#using-stringified-json-in-rest-queries) | ||
| in a REST query. | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add a URL example of stringified JSON format for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for reminding me! I just realized that the url works well with the stringified JSON ( it has a bug with pure url, see #4992). It will be a good workaround for |
||
| ### Examples | ||
|
|
||
| Return customer information only with `name` and `address`, and hide their `id`: | ||
|
|
||
| {% include code-caption.html content="Node.js API" %} | ||
|
|
||
| ```ts | ||
| await customerRepository.find({fields: {id: false, name: true, address: true}}); | ||
| ``` | ||
|
|
||
| {% include code-caption.html content="REST" %} | ||
|
|
||
| Include all required properties as a workaround: | ||
| `/customers?filter[fields][name]=true&filter[fields][address]=true` | ||
|
|
||
| Or use stringified JSON format: | ||
|
|
||
| `/orders?filter={"fields":{"name":true,"address":true,"id":false}}` | ||
|
|
||
| Returns: | ||
|
|
||
| ```ts | ||
| [ | ||
| { | ||
| name: 'Mario', | ||
| address: '8200 Warden Ave' | ||
| }, | ||
| { | ||
| name: 'Luigi', | ||
| address: '999 Avenue Rd' | ||
| }, | ||
| ... | ||
| ] | ||
| ``` | ||
|
|
||
| Exclude the `password` property: | ||
|
|
||
| {% include code-caption.html content="Node.js API" %} | ||
|
|
||
| ```ts | ||
| await userRepository.find({fields: {password: false}}); | ||
| ``` | ||
|
|
||
| {% include code-caption.html content="REST" %} | ||
|
|
||
| Include all properties except `password` as a workaround: | ||
|
|
||
| `/users?filter[fields][name]=true&filter[fields][email]=true&filter[fields][id]=true...` | ||
hacksparrow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Or use stringified JSON format: | ||
|
|
||
| `/users?filter={"fields":{"password":false}}` | ||
|
|
||
| Notice that `fields` clause is to include/exclude the result from the | ||
| **database**, e.g if you would like to check `password` for users, the above | ||
| example would fail as `password` is undefined. If you need the property and also | ||
| want to hide it from the response, set it as a | ||
| [hidden property](Model.md#hidden-properties) in the model definition. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,273 @@ | ||
| --- | ||
| title: 'Include filter' | ||
| lang: en | ||
| keywords: LoopBack 4.0, LoopBack 4, include | ||
| sidebar: lb4_sidebar | ||
| permalink: /doc/en/lb4/Include-filter.html | ||
| --- | ||
|
|
||
| An *include* filter enables you to include results from related models in a | ||
| query over relations. (See [Relations](Relations.md) for details on how to | ||
| define relations) | ||
|
|
||
| The value of the include filter can be a string, an array, or an object. | ||
|
|
||
| {% include important.html content="You can use an _include_ filter with `find(),` `findOne()` and `findById()` methods. | ||
| " %} | ||
|
|
||
| ### Node.js API | ||
|
|
||
| {% include content/angular-methods-caveat.html lang=page.lang %} | ||
|
|
||
| To query one relation: | ||
|
|
||
| ```ts | ||
| { | ||
| include: [{relation: 'relationName'}]; | ||
| } | ||
| ``` | ||
|
|
||
| To query multiple relations: | ||
|
|
||
| ```ts | ||
| { | ||
| include: [{relation: 'relationName1'}, {relation: 'relationName2'}]; | ||
| } | ||
| ``` | ||
|
|
||
| To query nested relations, use the scope field: | ||
|
|
||
| ```ts | ||
| { | ||
| relation: 'relationName', | ||
| scope: { | ||
| include: [{relation: 'nestedRelationName'}], | ||
| }, | ||
| } | ||
| ``` | ||
|
|
||
| Where: | ||
|
|
||
| - _relationName_ is the name of a relation defined in repositories. Check | ||
| [Relations](Relations.md) for details. | ||
|
|
||
| ### REST API | ||
|
|
||
| To query one relation: `/modelName?filter[include][][relation]=_relationName_` | ||
|
|
||
| To query multiple relations: | ||
| `/modelName?filter[include][0][relation]=_relationName1_&filter[include][1][relation]=_relationName2_` | ||
|
|
||
| To query nested relations, as the url would get too long, we recommend to encode | ||
| it with `encodeURIComponent(JSON.stringify(filter))`: | ||
| `/modelName?filter=<encodeResult>` | ||
|
|
||
| You can also use | ||
| [stringified JSON format](Querying-data.md#using-stringified-json-in-rest-queries) in | ||
| a REST query. | ||
|
|
||
| ### Examples | ||
|
|
||
| - Return all customers with their orders: | ||
|
|
||
| {% include code-caption.html content="Node.js API" %} | ||
|
|
||
| ```ts | ||
| await customerRepository.find({include: [{relation: 'orders'}]}); | ||
| ``` | ||
|
|
||
| {% include code-caption.html content="REST" %} | ||
|
|
||
| `/customers?filter[include][][relation]=orders` | ||
|
|
||
| Or stringified JSON format: | ||
|
|
||
| `/customers?filter={"include":[{"relation":"orders"}]}` | ||
|
|
||
| Result: | ||
|
|
||
| ```ts | ||
| [{ | ||
| id: 1, | ||
| name: 'Tom Nook', | ||
| orders:[{id: 1, desc: 'pencil'}] | ||
| }, | ||
| {...} | ||
| ] | ||
| ``` | ||
|
|
||
| - Return all customers with their orders and their address: | ||
|
|
||
| {% include code-caption.html content="Node.js API" %} | ||
|
|
||
| ```ts | ||
| await customerRepository.find({ | ||
| include: [{relation: 'orders'}, {relation: 'address'}], | ||
| }); | ||
| ``` | ||
|
|
||
| {% include code-caption.html content="REST" %} | ||
|
|
||
| `/customers?filter[include][0][relation]=orders?filter[include][1][relation]=address` | ||
|
|
||
| Result: | ||
|
|
||
| ```ts | ||
| [{ | ||
| id: 1, | ||
| name: 'Tom Nook', | ||
| orders:[{id: 1, desc: 'pencil'}], | ||
| address: {'8200 Warden Ave'} | ||
| }, | ||
| {...} | ||
| ] | ||
| ``` | ||
|
|
||
| - Return all customers with their orders and also the shipment information of | ||
| orders: | ||
|
|
||
| {% include code-caption.html content="Node.js API" %} | ||
|
|
||
| ```ts | ||
| await customerRepository.find({ | ||
| include: [ | ||
| { | ||
| relation: 'orders', | ||
| scope: { | ||
| include: [{relation: 'shipment'}], | ||
| }, | ||
| }, | ||
| ], | ||
| }); | ||
| ``` | ||
|
|
||
| {% include code-caption.html content="REST" %} | ||
|
|
||
| (using `encodeURIComponent`) | ||
|
|
||
| ``` | ||
| /customers?filter=%7B"include"%3A%5B%7B"relation"%3A"orders"%2C"scope"%3A%7B"include"%3A%5B%7B"relation"%3A"shipment"%7D%5D%7D%7D%5D%7D | ||
| ``` | ||
|
|
||
| Result: | ||
|
|
||
| ```ts | ||
| [{ | ||
| id: 1, | ||
| name: 'Tom Nook', | ||
| orders:[ | ||
| {id: 123, | ||
| desc: 'pencil', | ||
| shipment: {id: 999, company: 'UPS'} // nested related models | ||
| } | ||
| ], | ||
| }, | ||
| {...} | ||
| ] | ||
| ``` | ||
|
|
||
| #### Combined use of `fields` and `include` for a `belongsTo` relation | ||
agnes512 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| If you want to use both `include` and [`fields`](Fields-filter.md) to display | ||
| only specific fields of a model and a specific belongsTo relation, **you need to | ||
| add the relation foreign key in the `fields`** : | ||
|
|
||
| Return all posts only with field `title` and the relation `category`: | ||
|
|
||
| ```ts | ||
| await postRepository.find({include: [{relation: 'category'}], fields: ['title', 'categoryId'}); | ||
| ``` | ||
|
|
||
| #### Include with filters | ||
|
|
||
| In some cases, you may want to apply filters to related models to be included. | ||
|
|
||
| {% include note.html content=" | ||
|
|
||
| When you apply filters to related models, the query returns results from the | ||
| first model plus any results from related models with the filter query, similar | ||
| to a \"left join\" in SQL. | ||
|
|
||
| " %} | ||
|
|
||
| LoopBack supports that with the following syntax (for example): | ||
|
|
||
| ```ts | ||
| await postRepository.find({ | ||
| include: [ | ||
| { | ||
| relation: 'owner', // include the owner object | ||
| scope: { | ||
| // further filter the owner object | ||
| fields: ['username', 'email'], // only show two fields | ||
| include: { | ||
| // include orders for the owner | ||
| relation: 'orders', | ||
| scope: { | ||
| where: {orderId: 5}, // only select order with id 5 | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| ], | ||
| }); | ||
| ``` | ||
|
|
||
| For real-world scenarios where only users in `$authenticated` or `$owner` roles | ||
| should have access, use `findById()`. For example, the following example uses | ||
| filters to perform pagination: | ||
|
|
||
| ```ts | ||
| await postRepository.findById('123', { | ||
| include: [ | ||
| { | ||
| relation: 'owner', | ||
| scope: { | ||
| // fetch 1st "page" with 5 entries in it | ||
| skip: 0, | ||
| limit: 5, | ||
| }, | ||
| }, | ||
| ], | ||
| }); | ||
| ``` | ||
|
|
||
| #### Access included objects | ||
|
|
||
| In the Node.js API, you can simply access the returned model instance with | ||
| related items as a plain JSON object. For example: | ||
|
|
||
| ```ts | ||
| const result = await postRepository.find({ | ||
| include: [{relation: 'owner'}, {relation: 'orders'}], | ||
| }); | ||
| console.log(result[0].owner, result[0].orders); | ||
| // log the related owner and order of the first returned instance | ||
| ``` | ||
|
|
||
| Note the relation properties such as `post.owner` reference a JavaScript | ||
| **function** for the relation method. | ||
|
|
||
| #### REST examples | ||
|
|
||
| These examples assume a customer model with a hasMany relationship to a reviews | ||
| model. | ||
|
|
||
| Return all customers including their reviews: | ||
|
|
||
| `/customers?filter[include][][relation]=reviews` | ||
|
|
||
| Return all customers including their reviews and also their orders: | ||
|
|
||
| `/customers?filter[include][0][relation]=reviews?filter[include][1][relation]=orders` | ||
|
|
||
| Return all customers whose age is 21, including their reviews: | ||
|
|
||
| `/customers?filter[include][][relation]=reviews&filter[where][age]=21` | ||
|
|
||
| Return first two customers including their reviews: | ||
|
|
||
| `/customers?filter[include][][relation]=reviews&filter[limit]=2` | ||
|
|
||
| **See also**: | ||
| [Querying related models](HasMany-relation.md#querying-related-models). | ||
Uh oh!
There was an error while loading. Please reload this page.