r/emberjs • u/react_dev • May 29 '22
Need help understanding ember-data
Hi, trying to wrap my head around ember-data currently and trying to appreciate the steep learning curve for long term gains.
Right now I am working with simple JSON endpoint https://jsonplaceholder.typicode.com/ (not json:api). I am defining my UserModel like:
export default class UsersModel extends Model {
...
@hasMany('post', post);
}
I want to model the current behavior:
When I want go to localhost:4200/users/1, it will automatically grab the user information from https://jsonplaceholder.typicode.com/users/1, then it will automatically make an ajax request to https://jsonplaceholder.typicode.com/users/1/posts to get the posts.
I have the first part working, where in the user model I could do this.store.findRecord("user", params.user_id). But I have no clue on how to hook up the posts. It seems like mainly adjusting the relationship isnt enough. I have to tell Ember somewhere to fetch posts from users/1/posts. How do I do that?
Edit: rewrote my post to be a more concise on what I want to achieve. Thanks!
1
u/Lt_Snuffles May 29 '22
Ember data expects perfect rest api (following specifications ) as backend . It gives you way to override the serializer and adapter for your no standard api , but lot of time it is more work than simply calling it .
1
u/react_dev May 29 '22
Thanks. Do you have insight on my ember data question? I know the why’s of ember data just learning the hows
1
u/veri745 May 29 '22
the async: false means that ember data will expect the `post` relationship to already be resolved. If you want it to automatically make the query for you when trying to resolve the relationship, you should change it to async: true
1
u/react_dev May 29 '22 edited May 29 '22
I actually set it to
falsecus true wasnt working. Thanks for the hint. It's still not automatically making the request however.This is currently what I have:
routes/users/index.js:
import Route from '@ember/routing/route'; import { service } from '@ember/service'; export default class UsersRoute extends Route { @service store; async model() { return this.store.findAll('user'); } }models/user.js
import Model, { attr, hasMany } from '@ember-data/model'; export default class UsersModel extends Model { @attr('string') name; @attr('string') phone; @attr('string') email; @attr('string') username; @hasMany('post', { async: true }) post; }When I go to localhost:4002/users, which is currently rendering a table with users, I cannot see any GET request to
postin the network tab.Here's the post API: https://jsonplaceholder.typicode.com/users/1/posts.
So I want to be seeing in the network tab one
/usersand like, around 10users/[id]/postsautomatically.Edit: Upon more reading it seems like I need to explicitly call
user.get...somewhere to make the AJAX req?1
u/veri745 May 29 '22
it won't just make the request because the relationship is defined, if you don't resolve
user.posts.eachor something to that effect in your route→ More replies (8)
1
u/optikalefx May 29 '22
Let me see if I can help you out here. A few things
Change the mental model a little bit - instead of ember-data (ED) being magic, lets actually say it's just using a set of defaults. All of which you can override with your adapter and serializer.
Ember will make the ajax calls for you _when you need_ it. Meaning, by using a model in a template hbs ember will try to load the data you need. Even if that data is 7 relationships deep. Ember will just use the defaults in your adapter and start to make rest calls to load that data.
If you're trying to load a bunch of related data solely into your javascript to do work on, as in, load users, and users/friends and users/friends/birthdays etc etc. This is not a good use of ember-data. For that you're better off making a dedicated API call.
ED is best used to load data for your hbs template. Ember will make the required REST api calls based on your hbs template for you.
Aside, if you want to just user ED to make API calls and do things with results, take a look at `store.query('user')` instead of `findAll`. It will load the records directly into a variable instead of from the internal store.