You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/markdown/tutorial/part-2/11-ember-data.md
+38-41Lines changed: 38 additions & 41 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,11 +34,12 @@ Chances are, as we keep working on this app, we will need to add more routes tha
34
34
35
35
Fortunately, we're not going to do any of that. As it turns out, there's a much better solution here: we can use EmberData! As its name implies, [EmberData](../../../models/) is a library that helps manage data and *[application state][TODO: link to application state]* in Ember applications.
36
36
37
-
There's a lot to learn about EmberData, but let's start by uncovering features that help with our immediate problem.
38
37
39
38
> Zoey says...
40
39
>
41
-
> RequestManager is available starting with the EmberData 4.12 LTS release. EmberData works with multiple versions of Ember, please refer to the Compatibility section of the [EmberData README](https://github.com/emberjs/data/blob/main/README.md#compatibility) while doing your application upgrade.
40
+
> EmberData is in the process of being renamed to WarpDrive. It's not just changing its name though, WarpDrive is now able to be used in multiple different frameworks. You can read more about it in the [WarpDrive Docs](https://warp-drive.io)
41
+
42
+
There's a lot to learn about EmberData, but let's start by uncovering features that help with our immediate problem.
42
43
43
44
## EmberData Models
44
45
@@ -47,7 +48,7 @@ EmberData is built around the idea of organizing your app's data into *[model ob
@@ -71,7 +72,7 @@ export default class RentalModel extends Model {
71
72
}
72
73
```
73
74
74
-
Here, we created a `RentalModel` class that extends EmberData's `Model` superclass. When fetching the listing data from the server, each individual rental property will be represented by an instance (also known as a *[record](../../../models/finding-records/)*) of our `RentalModel` class.
75
+
Here, we created a `RentalModel` class that extends EmberData's `Model` superclass (which is imported from the `@warp-drive/legacy` package). When fetching the listing data from the server, each individual rental property will be represented by an instance (also known as a *[record](../../../models/finding-records/)*) of our `RentalModel` class.
75
76
76
77
We used the `@attr` decorator to declare the attributes of a rental property. These attributes correspond directly to the `attributes` data we expect the server to provide in its responses:
77
78
@@ -151,17 +152,32 @@ The generator created some boilerplate code for us, which serves as a pretty goo
151
152
152
153
This model test is also known as a *[unit test](../../../testing/testing-models/)*. Unlike any of the other tests that we've written thus far, this test doesn't actually *render* anything. It just instantiates the rental model object and tests the model object directly, manipulating its attributes and asserting their value.
153
154
154
-
It is worth pointing out that EmberData provides a `store` *[service](../../../services/)*, also known as the EmberData store. In our test, we used the `this.owner.lookup('service:store')` API to get access to the EmberData store. The store provides a `createRecord` method to instantiate our model object for us. To make this `store` service available, we must add the following file:
155
+
It is worth pointing out that EmberData provides a `store` *[service](../../../services/)*, also known as the EmberData store. In our test, we used the `this.owner.lookup('service:store')` API to get access to the EmberData store. The store provides a `createRecord` method to instantiate our model object for us.
156
+
157
+
This is the store that is generated for us as part of the default blueprint:
@@ -242,9 +258,9 @@ Wow... that removed a lot of code! This is all possible thanks to the power of c
242
258
243
259
## The EmberData Store
244
260
245
-
As mentioned above, EmberData provides a `store` service, which we can inject into our route using the `@service store;` declaration, making the EmberData store available as `this.store`. It provides the `request` method for making fetch requests using `RequestManager`. As its name implies: the `RequestManager` is request centric. Instead of answering questions about specific records or types of records, we ask it about the status of a specific request. To initiate a request, we use the `request` method on the store, passing in a request object. The request object is created using builders from `@ember-data/json-api/request`. Specifically, the [`findRecord` builder](../../../models/finding-records/#toc_retrieving-a-single-record) takes a model type (`rental` in our case) and a model ID (for us, that would be `params.rental_id` from the URL) as arguments and builds fetch options for a single record. On the other hand, the [`query` builder](../../../models/finding-records/#toc_retrieving-multiple-records) takes the model type as an argument and builds fetch options to query for all records of that type.
261
+
As mentioned above, EmberData provides a `store` service, which we can inject into our route using the `@service store;` declaration, making the EmberData store available as `this.store`. It provides the `request` method for making fetch requests using `RequestManager`. As its name implies: the `RequestManager` is request centric. Instead of answering questions about specific records or types of records, we ask it about the status of a specific request. To initiate a request, we use the `request` method on the store, passing in a request object. The request object is created using builders from `@warp-drive/utilities/json-api`. Specifically, the [`findRecord` builder](../../../models/finding-records/#toc_retrieving-a-single-record) takes a model type (`rental` in our case) and a model ID (for us, that would be `params.rental_id` from the URL) as arguments and builds fetch options for a single record. On the other hand, the [`query` builder](../../../models/finding-records/#toc_retrieving-multiple-records) takes the model type as an argument and builds fetch options to query for all records of that type.
246
262
247
-
EmberData can do many things, and in default setup it provides caching. EmberData's store caches server responses, allowing instant access to previously fetched data. If the data is already cached, you don't need to wait for the server to respond again. If not, the store fetches it for you.
263
+
EmberData can do many things, and in the default setup it provides caching. EmberData's store caches server responses, allowing instant access to previously fetched data. If the data is already cached, you don't need to wait for the server to respond again. If not, the store fetches it for you.
248
264
249
265
That's a lot of theory, but is this going to work in our app? Let's run the tests and find out!
250
266
@@ -273,7 +289,7 @@ The first thing we want to do is have our builder respect a configurable default
As you can see, the handler appends `.json` to the URL of each request. Pretty simple, right? Then it calls the `next` function with the modified copy of the request object (because it is immutable). This is how we can chain multiple handlers together to build up a request.
299
315
300
-
The next step that we need to do, is to configure `RequestManager` to use this handler. Let's create the request-manager service.
import BaseRequestManager from '@ember-data/request';
304
-
import Fetch from '@ember-data/request/fetch';
305
-
import { JsonSuffixHandler } from 'super-rentals/utils/handlers';
306
-
307
-
export default class RequestManager extends BaseRequestManager {
308
-
constructor(args) {
309
-
super(args);
310
-
311
-
this.use([JsonSuffixHandler, Fetch]);
312
-
}
313
-
}
314
-
```
315
-
316
-
Notice that we are using the `JsonSuffixHandler` we created earlier. We also use the `Fetch` handler, which is a built-in handler that makes the actual fetch request. The`use` method is used to add handlers to the request manager. The order in which handlers are added is important, as they will be executed in the order they were added.
317
-
318
-
Lastly, let's update our `store` service to use the new `RequestManager` we created.
316
+
The next step that we need to do, is to configure our `legacyStore` to use this handler. Let's update the store service to add this handler:
0 commit comments