From 76bf1f7b7475439de7b5762f473836b94f599b64 Mon Sep 17 00:00:00 2001 From: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> Date: Fri, 31 May 2024 14:37:19 +0530 Subject: [PATCH 1/5] draft: initial changes to finding record using request manager paradigm --- guides/release/models/finding-records.md | 41 +++++++++++++----------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/guides/release/models/finding-records.md b/guides/release/models/finding-records.md index ef3de53b32..f316ae00e8 100644 --- a/guides/release/models/finding-records.md +++ b/guides/release/models/finding-records.md @@ -2,15 +2,17 @@ The EmberData store provides an interface for retrieving records of a single typ ### Retrieving a Single Record -Use [`store.findRecord()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/findRecord?anchor=findRecord) to retrieve a record by its type and ID. -This will return a promise that fulfills with the requested record: +Use [`findRecord()`](https://api.emberjs.com/ember-data/5.3/functions/@ember-data%2Fjson-api%2Frequest/findRecord) to retrieve a record by its type and ID. +This will return a response from the server which has a requested record: ```javascript -// GET /blog-posts/1 -this.store.findRecord('blog-post', 1) // => GET /blog-posts/1 - .then(function(blogPost) { - // Do something with `blogPost` - }); +// GET /blog-post/1 +import { service } from '@ember/service'; +import { findRecord } from '@ember-data/json-api/request'; + +@service store +const result = await this.store.request(findRecord('blog-post', '1')); +const blog-post = result.content.data; ``` Use [`store.peekRecord()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/peekRecord?anchor=peekRecord) to retrieve a record by its type and ID, without making a network request. @@ -22,14 +24,14 @@ let blogPost = this.store.peekRecord('blog-post', 1); // => no network request ### Retrieving Multiple Records -Use [`store.findAll()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/findAll?anchor=findAll) to retrieve all of the records for a given type: +Use [`query()`](https://api.emberjs.com/ember-data/5.3/functions/@ember-data%2Fjson-api%2Frequest/query) to retrieve all of the records for a given type: ```javascript // GET /blog-posts -this.store.findAll('blog-post') // => GET /blog-posts - .then(function(blogPosts) { - // Do something with `blogPosts` - }); +import { query } from '@ember-data/json-api/request'; + +const result = await store.request(query('blog-post')); +const blog-posts = result.content.data; ``` Use [`store.peekAll()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/peekAll?anchor=peekAll) to retrieve all of the records for a given type that are already loaded into the store, without making a network request: @@ -38,7 +40,7 @@ Use [`store.peekAll()`](https://api.emberjs.com/ember-data/release/classes/Store let blogPosts = this.store.peekAll('blog-post'); // => no network request ``` -`store.findAll()` returns a `PromiseArray` that fulfills to a `RecordArray` and `store.peekAll` directly returns a `RecordArray`. +`findRecord()` returns a `PromiseArray` that fulfills to a `RecordArray` and `store.peekAll` directly returns a `RecordArray`. It's important to note that `RecordArray` is not a JavaScript array, it's an object that implements [`MutableArray`](https://api.emberjs.com/ember/release/classes/MutableArray). This is important because, for example, if you want to retrieve records by index, @@ -47,21 +49,22 @@ the `[]` notation will not work--you'll have to use `objectAt(index)` instead. ### Querying for Multiple Records EmberData provides the ability to query for records that meet certain criteria. -Calling [`store.query()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/query?anchor=query) will make a `GET` request with the passed object serialized as query params. -This method returns a `PromiseArray` in the same way as `findAll`. +Calling [`query()`](https://api.emberjs.com/ember-data/5.3/functions/@ember-data%2Fjson-api%2Frequest/query) will make a `GET` request with the passed object serialized as query params. +This method returns a respone from the server in the same way as `findRecord`. For example, we could search for all `person` models who have the name of `Peter`: ```javascript // GET to /persons?filter[name]=Peter -this.store.query('person', { +import { query } from '@ember-data/json-api/request'; + +const result = await store.request(query('person', { filter: { name: 'Peter' } -}).then(function(peters) { - // Do something with `peters` -}); +})); +const person = result.content.data; ``` ### Querying for A Single Record From 3f1f5e0850f5617a0129159ac05e4b628dfddacf Mon Sep 17 00:00:00 2001 From: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:11:03 +0530 Subject: [PATCH 2/5] add: querying single data migration to use request manager --- guides/release/models/finding-records.md | 56 ++++++++++++------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/guides/release/models/finding-records.md b/guides/release/models/finding-records.md index f316ae00e8..e3a8064101 100644 --- a/guides/release/models/finding-records.md +++ b/guides/release/models/finding-records.md @@ -10,9 +10,9 @@ This will return a response from the server which has a requested record: import { service } from '@ember/service'; import { findRecord } from '@ember-data/json-api/request'; -@service store +// somewhere in the app const result = await this.store.request(findRecord('blog-post', '1')); -const blog-post = result.content.data; +const blogPost = result.content.data; ``` Use [`store.peekRecord()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/peekRecord?anchor=peekRecord) to retrieve a record by its type and ID, without making a network request. @@ -31,7 +31,7 @@ Use [`query()`](https://api.emberjs.com/ember-data/5.3/functions/@ember-data%2Fj import { query } from '@ember-data/json-api/request'; const result = await store.request(query('blog-post')); -const blog-posts = result.content.data; +const blogPosts = result.content.data; ``` Use [`store.peekAll()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/peekAll?anchor=peekAll) to retrieve all of the records for a given type that are already loaded into the store, without making a network request: @@ -69,9 +69,9 @@ const person = result.content.data; ### Querying for A Single Record -If you are using an adapter that supports server requests capable of returning a single model object, -EmberData provides a convenience method [`store.queryRecord()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/queryRecord?anchor=queryRecord) that will return a promise that resolves with that single record. -The request is made via a method `queryRecord()` defined by the adapter. +If you are using an builder that supports server requests capable of returning a single model object, +EmberData provides a convenience method [`findRecord()`](https://api.emberjs.com/ember-data/5.3/functions/@ember-data%2Fjson-api%2Frequest/findRecord) that will return a record. +The request is made via a method `findRecord()` defined by the builders. For example, if your server API provides an endpoint for the currently logged in user: @@ -85,43 +85,43 @@ For example, if your server API provides an endpoint for the currently logged in } ``` -And if the adapter for the `User` model defines a `queryRecord()` method that targets that endpoint: - -```javascript {data-filename=app/adapters/user.js} -import Adapter from '@ember-data/adapter'; -import fetch from 'fetch'; - -export default class UserAdapter extends Adapter { - queryRecord(store, type, query) { - return fetch('/api/current_user'); - } +And if the builders for the `User` model defines a `queryData()` method that targets that endpoint: + +```javascript {data-filename=app/builders/user.js} +export function queryData() { + return { + url: `/api/current_user`, + method: 'GET', + headers: { + 'Content-Type': 'application/json' + }, + } } ``` -Then, calling [`store.queryRecord()`](https://api.emberjs.com/ember-data/release/classes/Store/methods/queryRecord?anchor=queryRecord) will retrieve that object from the server: +Then, calling `queryData()` will retrieve that object from the server: ```javascript -store.queryRecord('user', {}).then(function(user) { - let username = user.get('username'); - console.log(`Currently logged in as ${username}`); -}); +import { queryData } from './builders'; + +const user = await this.requestManager.request(queryData()) +let username = user.get('username'); +console.log(`Currently logged in as ${username}`); ``` -As in the case of `store.query()`, a query object can also be passed to `store.queryRecord()` and is available for the adapter's `queryRecord()` to use to qualify the request. -However the adapter must return a single model object, not an array containing one element, +As in the case of `query()`, a query object can also be passed to `query()` and is available for the builder's `query()` to use to qualify the request. +However the builder must return a single model object, not an array containing one element, otherwise EmberData will throw an exception. -Note that Ember's default [JSON:API adapter](https://api.emberjs.com/ember-data/release/classes/JSONAPIAdapter) does not provide the functionality needed to support `queryRecord()` directly as it relies on REST request definitions that return result data in the form of an array. - -If your server API or your adapter only provides array responses but you wish to retrieve just a single record, you can alternatively use the `query()` method as follows: +If your server API or your builder only provides array responses but you wish to retrieve just a single record, you can alternatively use the `query()` method as follows: ```javascript // GET to /users?filter[email]=tomster@example.com -tom = store.query('user', { +tom = requestManager.request(queryData('user', { filter: { email: 'tomster@example.com' } -}).then(function(users) { +})).then(function(users) { return users[0]; // the first object }); ``` From 5d0b5c959bde7aec5d287fec1fc8830edcafba7f Mon Sep 17 00:00:00 2001 From: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> Date: Wed, 7 Aug 2024 01:33:12 +0530 Subject: [PATCH 3/5] fix: requested changes --- guides/release/models/finding-records.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/guides/release/models/finding-records.md b/guides/release/models/finding-records.md index e3a8064101..214838ce9a 100644 --- a/guides/release/models/finding-records.md +++ b/guides/release/models/finding-records.md @@ -19,7 +19,7 @@ Use [`store.peekRecord()`](https://api.emberjs.com/ember-data/release/classes/St This will return the record only if it is already present in the store: ```javascript -let blogPost = this.store.peekRecord('blog-post', 1); // => no network request +let blogPost = this.store.peekRecord('blog-post', '1'); // => no network request ``` ### Retrieving Multiple Records @@ -40,7 +40,7 @@ Use [`store.peekAll()`](https://api.emberjs.com/ember-data/release/classes/Store let blogPosts = this.store.peekAll('blog-post'); // => no network request ``` -`findRecord()` returns a `PromiseArray` that fulfills to a `RecordArray` and `store.peekAll` directly returns a `RecordArray`. +`findRecord()` returns a `response` which has the record and `store.peekAll` directly returns a `RecordArray`. It's important to note that `RecordArray` is not a JavaScript array, it's an object that implements [`MutableArray`](https://api.emberjs.com/ember/release/classes/MutableArray). This is important because, for example, if you want to retrieve records by index, @@ -104,8 +104,9 @@ Then, calling `queryData()` will retrieve that object from the server: ```javascript import { queryData } from './builders'; -const user = await this.requestManager.request(queryData()) +const user = await this.requestManager.request(queryData()); let username = user.get('username'); + console.log(`Currently logged in as ${username}`); ``` From 02142d433610f1ceb61841e549bbfe05dd85273a Mon Sep 17 00:00:00 2001 From: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> Date: Fri, 9 Aug 2024 22:17:32 +0530 Subject: [PATCH 4/5] Fix: rephrase --- guides/release/models/finding-records.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/release/models/finding-records.md b/guides/release/models/finding-records.md index 214838ce9a..be8f10d2e2 100644 --- a/guides/release/models/finding-records.md +++ b/guides/release/models/finding-records.md @@ -3,7 +3,7 @@ The EmberData store provides an interface for retrieving records of a single typ ### Retrieving a Single Record Use [`findRecord()`](https://api.emberjs.com/ember-data/5.3/functions/@ember-data%2Fjson-api%2Frequest/findRecord) to retrieve a record by its type and ID. -This will return a response from the server which has a requested record: +This will return a single `record` or a `array` depends upon the response from server: ```javascript // GET /blog-post/1 From 10ab3aae73605a3dbee049f30f40ab0e45a0e8a4 Mon Sep 17 00:00:00 2001 From: Mehul Kiran Chaudhari <55375534+MehulKChaudhari@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:00:56 +0530 Subject: [PATCH 5/5] fix: code snippets for consistency --- guides/release/models/finding-records.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guides/release/models/finding-records.md b/guides/release/models/finding-records.md index be8f10d2e2..0ebdd6a4f3 100644 --- a/guides/release/models/finding-records.md +++ b/guides/release/models/finding-records.md @@ -11,7 +11,7 @@ import { service } from '@ember/service'; import { findRecord } from '@ember-data/json-api/request'; // somewhere in the app -const result = await this.store.request(findRecord('blog-post', '1')); +const result = await store.request(findRecord('blog-post', '1')); const blogPost = result.content.data; ``` @@ -104,7 +104,7 @@ Then, calling `queryData()` will retrieve that object from the server: ```javascript import { queryData } from './builders'; -const user = await this.requestManager.request(queryData()); +const user = await requestManager.request(queryData()); let username = user.get('username'); console.log(`Currently logged in as ${username}`);