I have a modelA
, modelB
, and modelC
. modelA
hasMany modelB
, modelB
belongsTo modelA
, modelB
belongsTo modelC
.
Below is my computed property on my component.js
and the code below is I want to get all the modelA
where the modelC
id is equal to the baz.id
foo: computed('modelA', 'baz.id', function() {
return this.get('modelA').filter((a) => {
return a.get('modelB').filter((b) => {
let userId = b.get('modelC.id');
let bazId = this.get('baz.id');
if (userId === bazId) {
return b;
}
})
});
}),
Issue: I am not getting the correct response. The response is not equivalent to my expectations.
Question: Did I implement the computed property correctly based on my desired scenario which is I want to get all the modelA
where the modelC
id is equal to the baz.id
Appreciate for any response. Thank you
Ola @Mikelemuel, thanks for your question 🎉
I'm having a bit of difficulty in understanding what you're trying to ask 🤔I'm going to first lay out what I think you are asking and then proceed to answer the question as I understand it.
Firstly you say I want to get all the modelA where the modelC id is equal to the baz.id
which is hard to understand. Firstly I would recommend that you don't call these modelA
etc. because it's hard to figure out what you're asking and it's hard to forumulate an answer. If you can give me proper names for these models I will update them in this answer.
Based on what I understand of your relationships this is the setup that I have created:
// app/models/model-a.js
import DS from 'ember-data';
export default DS.Model.extend({
children: DS.hasMany('modelB'),
})
// app/models/model-b.js
import DS from 'ember-data';
export default DS.Model.extend({
parent: DS.belongsTo('modelA'),
sibling: DS.belongsTo('modelC'),
})
// app/models/model-c.js
import DS from 'ember-data';
export default DS.Model.extend({
sibling: DS.belongsTo('modelB'),
})
I built these models from the description of the relationships that you gave. Please let me know if they are incorrect or if you have a better name for each of the attribute names.
Now to rephrase the query that you're looking for:
I want to filter all model-a (which is the main query) where they have any children who's sibling has an ID equal to the id of this.baz
With this, I created a simple route that just creates some dummy data. This isn't important to the answer but it's useful to see what I'm trying to achieve:
// app/routes/application.js
import Route from '@ember/routing/route';
export default Route.extend({
model() {
let result = this.store.createRecord('model-a');
let children = [
this.store.createRecord('model-b', {
parent: result
}),
this.store.createRecord('model-b', {
parent: result
})
];
this.store.createRecord('model-c', {
id: 'five',
sibling: children[1]
});
return [result];
}
});
and with that we are able to create the computed property you were describing in the controller:
// app/controllers/application.js
import Controller from '@ember/controller';
import { computed } from '@ember/object';
export default Controller.extend({
baz: computed(function() {
return {
id: 'five',
}
}),
foo: computed('model', 'baz.id', function() {
let result = this.model.filter((item) => {
return item.children.find((child) => {
return child.get('sibling.id') === this.get('baz.id');
})
});
return result;
}),
});
firstly you will see that I have a baz
computed property that I'm just using to make it so that this.get('baz.id')
returns something. I imagine in your use case you're setting this.baz
to be something dynamically.
The next thing that you will notice is that I'm using a mixture of filter()
and find()
in my function. It is worth reminding yourself how filter()
works by checking out the JavaScript documentation but essentially you need to return a truthy value for the item in the array to be included in the result.
To provide this truthy value we are making use of JavaScript find which will find the first instance where the result of the provided function is truthy.
I have tested this locally and it works as expected (based on my understanding of your question).
I hope this was helpful 👍