Reading out members of a related model in a controller - javascript

I have two models in a relationship.
Level
App.Level = DS.Model.extend({
title: DS.attr(),
description: DS.attr(),
results: DS.hasMany('levelresult', {
async: true
})
});
App.Level.FIXTURES = [{
id: 1,
title: "Lorem Ipsum",
description: "Lorem Ipsum dollor sit amet",
results: [100,101]
}];
and Levelresult
App.Levelresult = DS.Model.extend({
minutes: DS.attr('number'),
seconds: DS.attr('number'),
points: DS.attr('number'),
failures: DS.attr('number'),
level: DS.belongsTo('level')
});
App.Levelresult.FIXTURES = [{
id: 100,
minutes: 44,
seconds: 23,
points: 7,
failures: 0,
level: 1
}, {
id: 101,
minutes: 12,
seconds: 33,
points: 4,
failures: 22,
level: 1
}];
So I declared a route for the parent(-resource)-template like this:
App.LevelRoute = Ember.Route.extend({
model: function (params) {
return this.store.find('level', params.level_id);
}
});
Its easy to work with them into the level/result-template. Even the related model (as a member of the Level-Model) Levelresult is available within the template (e.a. {{#each result in results}}).
Now I want to pick just a single entry out of the related Levelresult's (e.a. "101").
But in the nested route CONTROLLER (level/result as said before) I cant read any member except "id"
App.LevelResultController = Ember.ArrayController.extend({
getBestResult: function() {
var results = this.get('results');
results.forEach(function(result) {
console.log(result.get('id')); //Output: "100" and "101" --> correct
console.log(result.get('minutes')); //Output: "Undefined" and "Undefined" --> WHY?
}
//... Pick out the best one ...
}.property('results')
});
I don't get it, why reading "id" simply works but other members wont.

Related

Best way to return a nested object the matches a property requested

I'm trying to create a new object that only contains the a product array with the seller I req. I have an order object that has a product array. I'd like to return a specific seller. I tried:
const newOrders = orders.map((element) => {
return {
...element,
product: element.product.filter(
(seller) => seller === req.currentUser!.id
),
};
});
does mongoose have a preferred method for doing what I bring to achieve? I've read through the find queries but none of the methods seem useful to this use case.
orders: [
{
userId: "638795ad742ef7a17e258693",
status: "pending",
shippingInfo: {
line1: "599 East Liberty Street",
line2: null,
city: "Toronto",
country: "CA",
postal_code: "M7K 8P3",
state: "MT"
},
product: [
{
title: "new image",
description: "a log description",
seller: "6369589f375b5196f62e3675",
__v: 1,
id: "63737e4b0adf387c5e863d33"
},
{
title: "Mekks",
description: "Ple",
seller: "6369589f375b5196f62e3675",
__v: 1,
id: "6376706808cf1adafd5af32f"
},
{
title: "Meeks Prodyuct",
description: "long description",
seller: "63868795a6196afbc3677cfe",
__v: 1,
id: "63868812a6196afbc3677d06"
}
],
version: 1,
id: "6388138170892249e01bdcba"
}
],
Im sure this can be improved, doesn't feel that its the best way possible but it gets the result. Like the previous answer you have to find first the order the seller is in then find the products than filter the seller by the id. I'm using typescript and there's a bug https://github.com/microsoft/TypeScript/issues/50769 so you have to use the bracket notation.
const orders = await Order.find({
"product.seller": req.currentUser!.id,
});
const allOrders = orders[0].product;
const sellerOrders = allOrders.filter((obj) => {
return obj["seller"] === req.currentUser!.id;
});

Issue finding mongoose ObjectID in array of strings representing ObjectIDs

I need to find the index of the mongoose objectID in an array like this:
[ { _id: 58676b0a27b3782b92066ab6, score: 0 },
{ _id: 58676aca27b3782b92066ab4, score: 3 },
{ _id: 58676aef27b3782b92066ab5, score: 0 }]
The model I am using to compare is a mongoose schema with the following data:
{_id: 5868d41d27b3782b92066ac5,
updatedAt: 2017-01-01T21:38:30.070Z,
createdAt: 2017-01-01T10:04:13.413Z,
recurrence: 'once only',
end: 2017-01-02T00:00:00.000Z,
title: 'Go to bed without fuss / coming down',
_user: 58676aca27b3782b92066ab4,
__v: 0,
includeInCalc: true,
result: { money: 0, points: 4 },
active: false,
pocketmoney: 0,
goals: [],
pointsawarded: { poorly: 2, ok: 3, well: 4 },
blankUser: false }
I am trying to find the index of the model._user in the array above using the following:
var isIndex = individualScores.map(function(is) {return is._id; }).indexOf(taskList[i]._user);
Where individualScores is the original array and taskList[i] is the task model. However, this always returns -1. It never finds the correct _id in the array.
I guess your problem is related to how _id are returned by your query
If you get _id as String, your code should work, check the snippet below
But if instead, you get ObjectsIds, you have to cast them to String first
var individualScores = [
{ _id: "58676b0a27b3782b92066ab6", score: 0 },
{ _id: "58676aca27b3782b92066ab4", score: 3 },
{ _id: "58676aef27b3782b92066ab5", score: 0 }
]
var task = {
_id: "5868d41d27b3782b92066ac5",
updatedAt: new Date("2017-01-01T21:38:30.070Z"),
createdAt: new Date("2017-01-01T10:04:13.413Z"),
recurrence: 'once only',
end: new Date("2017-01-02T00:00:00.000Z"),
title: 'Go to bed without fuss / coming down',
_user: "58676aca27b3782b92066ab4",
__v: 0,
includeInCalc: true,
result: { money: 0, points: 4 },
active: false,
pocketmoney: 0,
goals: [],
pointsawarded: { poorly: 2, ok: 3, well: 4 },
blankUser: false
}
var isIndex = individualScores.map(
function(is) {
return is._id;
})
.indexOf(task._user);
console.log(isIndex)
I think your process should working well that you are using just only need to convert 'objectID' to String to compare. Convert using .toString() for both of _id and _user.
like bellow:
var isIndex = individualScores.map(function(is) {
return is._id.toString();
}).indexOf(taskList[i]._user.toString());

codeschool emberjs 7.4 rating a product not working

I have been battling the level 7.4 review question with no luck:
Rating isn’t a object like Review was, so our createRating function will be a little different. We can addObject the currently selected rating to the array of ratings on our product. You’ll need to save the product to update it in the store.
I can not seem to get the value from the select list. Can anyone point me in the right direction or collaborate on this?
My handlebars code:
<script type='text/x-handlebars' data-template-name='product'>
<div class='row'>
<div class='col-sm-7'>
<h2>{{title}}</h2>
<h3 class='text-success'>${{price}}</h3>
<p class='text-muted'>{{description}}</p>
<p class='text-muted'>This Product has a {{rating}} star rating!</p>
<p>Finely crafted by {{#link-to 'contact' crafter}}{{crafter.name}}{{/link-to}}.</p>
{{render 'reviews' reviews}}
<div class='new-rating'>
<h3>Rate {{title}}</h3>
</div>
<div class='new-review'>
<h3>Review {{title}}</h3>
{{#if text}}
<p class='text-muted'>{{text}}</p>
{{/if}}
{{textarea valueBinding='text'}}
<button {{action 'createReview'}} class='btn-primary'>Review</button>
</div>
</div>
<div class='col-sm-5'>
<img {{bind-attr src='image'}} class='img-thumbnail img-rounded'/>
</div>
</div>
{{contact-details contact=crafter className='row'}}
{{view Ember.Select content=ratings value=selectedRating}}
<button {{action 'createRating'}} class='btn-primary'>Rating</button>
</script>
My js code:
var App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function() {
this.route('credits', { path: '/thanks' });
this.resource('products', function() {
this.resource('product', { path: '/:product_id' });
this.route('onsale');
this.route('deals');
});
this.resource('contacts', function() {
this.resource('contact', { path: '/:contact_id' });
});
});
App.IndexController = Ember.ArrayController.extend({
productsCount: Ember.computed.alias('length'),
logo: 'images/logo-small.png',
time: function() {
return (new Date()).toDateString();
}.property(),
onSale: function() {
return this.filterBy('isOnSale').slice(0,3);
}.property('#each.isOnSale')
});
App.ContactsIndexController = Ember.Controller.extend({
contactName: 'Anostagia',
avatar: 'images/avatar.png',
open: function() {
return ((new Date()).getDay() === 0) ? "Closed" : "Open";
}.property()
});
App.ProductsController = Ember.ArrayController.extend({
sortProperties: ['title']
});
App.ContactsController = Ember.ArrayController.extend({
sortProperties: ['name'],
contactsCount: Ember.computed.alias('length')
});
App.ReviewsController = Ember.ArrayController.extend({
sortProperties: ['reviewedAt'],
sortAscending: false
});
App.ContactProductsController = Ember.ArrayController.extend({
sortProperties: ['title']
});
App.ProductController = Ember.ObjectController.extend({
text: '',
ratings: [1,2,3,4,5],
selectedRating: 5,
actions: {
createReview: function(){
var review = this.store.createRecord('review', {
text: this.get('text'),
product: this.get('model'),
reviewedAt: new Date()
});
var controller = this;
review.save().then(function() {
controller.set('text', '');
controller.get('model.reviews').addObject(review);
});
},
createRating: function(){
var rating = this.store.createRecord('rating', {
rating: this.get('selectedRating.value'),
product: this.get('model'),
reviewedAt: new Date()
});
var controller = this;
rating.save().then(function() {
controller.get('model.rating').addObject(rating);
});
}
}
});
App.ProductsRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('product');
}
});
App.ContactsRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('contact');
}
});
App.IndexRoute = Ember.Route.extend({
model: function(){
return this.store.findAll('product');
}
});
App.ProductsIndexRoute = Ember.Route.extend({
model: function(){
return this.store.findAll('product');
}
});
App.ProductsOnsaleRoute = Ember.Route.extend({
model: function(){
return this.modelFor('products').filterBy('isOnSale');
}
});
App.ProductsDealsRoute = Ember.Route.extend({
model: function(){
return this.modelFor('products').filter(function(product){
return product.get('price') < 500;
});
}
});
App.ProductDetailsComponent = Ember.Component.extend({
reviewsCount: Ember.computed.alias('product.reviews.length'),
hasReviews: function(){
return this.get('reviewsCount') > 0;
}.property('reviewsCount')
});
App.ContactDetailsComponent = Ember.Component.extend({
productsCount: Ember.computed.alias('contact.products.length'),
isProductive: function() {
return this.get('productsCount') > 3;
}.property('productsCount')
});
App.ProductView = Ember.View.extend({
isOnSale: Ember.computed.alias('controller.isOnSale'),
classNameBindings: ['isOnSale']
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Product = DS.Model.extend({
title: DS.attr('string'),
price: DS.attr('number'),
description: DS.attr('string'),
isOnSale: DS.attr('boolean'),
image: DS.attr('string'),
reviews: DS.hasMany('review', { async: true }),
crafter: DS.belongsTo('contact', { async: true }),
ratings: DS.attr(),
rating: function(){
return this.get('ratings').reduce(function(previousValue, rating) {
return previousValue + rating;
}, 0) / this.get('ratings').length;
}.property('ratings.#each')
});
App.Product.FIXTURES = [
{ id: 1,
title: 'Flint',
price: 99,
description: 'Flint is a hard, sedimentary cryptocrystalline form of the mineral quartz, categorized as a variety of chert.',
isOnSale: true,
image: 'images/products/flint.png',
reviews: [100,101],
crafter: 200,
ratings: [2,1,3,3]
},
{
id: 2,
title: 'Kindling',
price: 249,
description: 'Easily combustible small sticks or twigs used for starting a fire.',
isOnSale: false,
image: 'images/products/kindling.png',
reviews: [],
crafter: 201,
ratings: [2,1,3,3]
},
{
id: 3,
title: 'Matches',
price: 499,
description: 'One end is coated with a material that can be ignited by frictional heat generated by striking the match against a suitable surface.',
isOnSale: true,
reviews: [],
image: 'images/products/matches.png',
crafter: 201,
ratings: [2,1,3,3]
},
{
id: 4,
title: 'Bow Drill',
price: 999,
description: 'The bow drill is an ancient tool. While it was usually used to make fire, it was also used for primitive woodworking and dentistry.',
isOnSale: false,
reviews: [],
image: 'images/products/bow-drill.png',
crafter: 200,
ratings: [1,3,3]
},
{
id: 5,
title: 'Tinder',
price: 499,
description: 'Tinder is easily combustible material used to ignite fires by rudimentary methods.',
isOnSale: true,
reviews: [],
image: 'images/products/tinder.png',
crafter: 201,
ratings: [2,1,3]
},
{
id: 6,
title: 'Birch Bark Shaving',
price: 999,
description: 'Fresh and easily combustable',
isOnSale: true,
reviews: [],
image: 'images/products/birch.png',
crafter: 201,
ratings: [2,3,5]
}
];
App.Contact = DS.Model.extend({
name: DS.attr('string'),
about: DS.attr('string'),
avatar: DS.attr('string'),
products: DS.hasMany('product', { async: true })
});
App.Contact.FIXTURES = [
{
id: 200,
name: 'Giamia',
about: 'Although Giamia came from a humble spark of lightning, he quickly grew to be a great craftsman, providing all the warming instruments needed by those close to him.',
avatar: 'images/contacts/giamia.png',
products: [1,4]
},
{
id: 201,
name: 'Anostagia',
about: 'Knowing there was a need for it, Anostagia drew on her experience and spearheaded the Flint & Flame storefront. In addition to coding the site, she also creates a few products available in the store.',
avatar: 'images/contacts/anostagia.png',
products: [2,3,5,6]
}
];
App.Review = DS.Model.extend({
text: DS.attr('string'),
reviewedAt: DS.attr('date'),
product: DS.belongsTo('product')
});
App.Review.FIXTURES = [
{
id: 100,
text: "Started a fire in no time!"
},
{
id: 101,
text: "Not the brightest flame, but warm!"
}
];
After detailed research, the answer turned out being:
createRating: function() {
var prod = this.get('model');
var ratings = this.get('model.ratings');
ratings.addObject(this.selectedRating);
prod.save();
}
In the code shown, you should be getting the rating using this.get('selectedRating') not this.get('selectedRating.value')
http://emberjs.jsbin.com/xohidixe/1/edit

UnderscoreJS wont extend object

I am trying to merge 2 objects using underscore. The destination object is a mongoose model but I have applied lean() to it to make it return a javascript object rather than a mongo document.
model.find({}).lean().exec(function (error, object) {});
I then try extending using underscore
_.extend(object, source);
But it only returns the source object.
I have tried with simple objects to test and those worked fine, so I am assuming it has something to do with mongoose?
The simple objects that worked were:
{foo:'foo'},{bar:'bar'}
And the objects that I am trying to merge but haven't been able to are:
{
_id: 526540eaa77883d815000029,
name: 'House',
description: '',
type: 'residential',
cost: 100,
buildTime: 5,
resources: { produces: [], required: { wood: 5 } },
population: { provides: 10, required: 0 },
requires: [],
maxLevel: 5,
upgrades:
{ '2': { resourceMultiplier: 1.2, cost: 150, time: 5 },
'3': { resourceMultiplier: 1.5, cost: 200, time: 7 },
'4': { resourceMultiplier: 2, cost: 300, time: 10 },
'5': { resourceMultiplier: 2.5, cost: 500, time: 15 } },
scale: { x: 1, y: 1, z: 1 }
}
{
empireId: '52654578a4eff60000000001',
buildingId: '526540eaa77883d815000029',
level: 1,
isComplete: false,
isUpgrading: false,
gridId: '175|0|125',
started: 1382442513823,
_id: 526666113fccae68be000003,
__v: 0
}
Anyone come across this before or know where I am going wrong?
Well I am stupid. The source object was gotten from another mongoose query at the top of the file, this one was an instance of mongoose.Document and therefore couldn't be changed. I added lean() to it to make it return a javascript object and it's all working now.

emberjs hasMany returns undefined

I'm trying to implement a minimal emberJs app using fixtures and a one-to-many relation between two models:
App.store = DS.Store.create({
revision: 11,
adapter: 'DS.FixtureAdapter'
});
App.Album = DS.Model.extend({
Name: DS.attr("string"),
Songs: DS.hasMany('App.Song')
});
App.Song = DS.Model.extend({
Name: DS.attr("string"),
Album: DS.belongsTo('App.Album')
});
App.Album.FIXTURES = [
{
id: 1,
Name: 'foo'
},
{
id: 2,
Name: 'bar'
}
];
App.Song.FIXTURES = [
{
id: 1,
Album_id: 1,
Name: "asdf"
},
{
id: 2,
Album_id: 2,
Name: "Test"
}
];
I can access the Album model through the console like this
App.Album.find(1).get('Name') # => foo
Whenever I try access the Songs property trough the relation between album and song I get undefined:
App.Album.find(1).get('Songs').objectAt(0) # undefined
Any hints what I might be doing wrong here?
You haven't defined which Songs an Album has. You need to specify Songs: [1,2,3] in your Album model.
(Quite sure it's Songs, but it may Song_ids.)

Categories