I want to change the header of my RESTAdapter after I loaded the user, but can't access the properties.
Any Ideas why ?
The related Code:
var user = '';
App.MainRoute = Ember.Route.extend({
model: function(params){
user = this.store.find('user',{email: params.email});
alert(user.hash); //get a undefined
return user;
},
actions:{
addList: function(){
var list = this.store.createRecord('list', {
name: 'New list',
desc: 'Describe it here'
});
this.store.find('user', 1).then(function(user){
list.set('user', user);
})
list.save();
}
}
})
The Json Response on this.store.find('user', {email: params.email});:
{
"users": [
{
"id": 1,
"hash": "66ff7d6eae591ca2a7d6b419991690e8",
"email": "marvin#blabla.de",
"name": "",
"lists": []
}
]
}
Model definitions: https://gist.github.com/Osile/5544ccab1997c4da2b5b
You have to return a Promise in Model, but you can also access it earlier. Code:
model: function(params){
users = this.store.find('user', { email: params.email }); // returns promise
users.then(function(item) { // resolves promise
user = item.get('firstObject');
alert(user.get('hash'));
});
return users; // model will wait for data
}
It works. You can use following Handlebars.js template:
<script type="text/x-handlebars" data-template-name="main">
From model:
<ul>
{{#each}} <!-- Iterate over array resolved from promise. -->
<li>{{hash}}</li>
{{/each}}
</ul>
</script>
Complete code: emberjs.jsbin.com
Related
I have two collections:
Posts: {_id: "123", text: "some text", user_id: "456"}
Bookmarks: {_id: "456", post_id: "123", user_id: "425" }
In the Bookmarks collection the post_id is the _id from the bookmarked post.
I use the following template helper to display all posts by specific user:
Template.profile.helpers({
posts: function () {
// get current router parameter id (iron router)
context = Router.current().params._id;
return Posts.find({user_id: context}, {sort: {timestamp: -1} } );
}
});
Now I would like to display all posts a user has bookmarked in a template: userBookmarks. Is it possible to achieve this with template helper ?
Or only with a package or the Mongo.Collection transform option ?
html:
<template name="userBookmarks">
{{#each myBookmarks}}
{{#with post}}
{{text}}
{{/with}}
{{/each}}
</template>
js:
Template.userBookmarks.helpers({
myBookmarks: function(){
return Bookmarks.find({user_id: Meteor.userId()});
},
post: function(){
return Posts.findOne({_id: this.post_id});
}
});
If you need a one-helper version:
Template.userBookmarks.helpers({
'posts': function () {
return Posts.find({
_id: {
$in: Bookmarks.find({user_id: Meteor.userId()}).map(function (bookmark) {
return bookmark.post_id;
})
}
});
}
});
I'm trying to display the names of each department. I handmade a 'department' model based off of another model i made that does work. Despite them being identical, #each will not loop through the 'departments' and list them.
departments.hbs >
{{#each model}}
<tr>
<td>
{{#linkTo 'department' this}}{{this.departmentName}}{{/linkTo}}
</td>
<td>{{this.departmentName}}</td>
</tr>
{{/each}}
No errors. It just doesn't list the departments.
VpcYeoman.DepartmentsView = Ember.View.extend({
templateName: 'departments'});
VpcYeoman.DepartmentView = Ember.View.extend({
templateName: 'department'
});
VpcYeoman.DepartmentsController = Ember.ObjectController.extend({
// Implement your controller here.
});
VpcYeoman.Department = DS.Model.extend({
departmentName: DS.attr('string'),
departmentMembers: DS.attr('string')
});
VpcYeoman.Department.reopen({
// certainly I'm duplicating something that exists elsewhere...
attributes: function(){
var attrs = [];
var model = this;
Ember.$.each(Ember.A(Ember.keys(this.get('data'))), function(idx, key){
var pair = { key: key, value: model.get(key) };
attrs.push(pair);
});
return attrs;
}.property()
});
VpcYeoman.Department.FIXTURES = [
{
id: 0,
departmentName: "Sickness",
departmentMembers: "61"
},
{
id: 1,
departmentName: "Health",
departmentMembers: "69"
}
];
'department/#/' DOES work. Why is {{#each model}} not able to find the list of departments?
EDIT:
VpcYeoman.DepartmentsController = Ember.ArrayController.extend({
// Implement your controller here.
});
Upon entering {{log model}} before the {{#each model)) loop, I get this response:
[nextObject: function, firstObject: undefined, lastObject: undefined, contains: function, getEach: function…]
__ember1386699686611_meta: Meta
length: 0
__proto__: Array[0]
VpcYeoman.DepartmentsRoute = Ember.Route.extend({
renderTemplate: function() {
this.render();
}
});
VpcYeoman.DepartmentRoute = Ember.Route.extend({});
You need to declare a DepartmentsRoute with the following:
VpcYeoman.DepartmentsRoute = Ember.Route.extend({
model: function() {
return this.store.find('department');
}
});
DepartmentsController should probably be an ArrayController, and you can view the model in the console to validate it has something using ((log model)) before your each
You need to implement a model hook, returning the departments
VpcYeoman.DepartmentsRoute = Ember.Route.extend({
model: function(){
return this.store.find('department');
},
renderTemplate: function() {
this.render();
}
});
the department route is guessing based on the route name and implementing the default model hook.
I have an ember application which has a number of users. Each of these users can be associated with a number of subjects. So I have a subjects model:
App.Subjects = DS.Model.extend({
subject : DS.attr('string'),
});
App.Subject.FIXTURES = [{
id: 1,
name: 'Sales',
}, {
id: 2,
name: 'Marketing',
}
];
and a users model:
App.User = DS.Model.extend({
name : DS.attr(),
email : DS.attr(),
subjects : DS.hasMany('subject'),
});
App.User.FIXTURES = [{
id: 1,
name: 'Jane Smith',
email: 'janesmith#thesmiths.com',
subjects: ["1", "2"]
}, {
id: 2,
name: 'John Dorian',
email: 'jd#sacredheart.com',
subjects: ["1", "2"]
}
];
I am having trouble representing this 1:M relationship in my templates. I have an edit user template (which Im also using to create a user) in which you can select the user's subjects via checkboxes. However, I want these checkboxes to be driven by the data in my subjects model. Is this possible? I have found very little documentation online and am very new to ember development. Here is my template:
<script type = "text/x-handlebars" id = "user/edit">
<div class="input-group">
<div class="user-edit">
<h5>User name</h5>
{{input value=name}}
<h5>User email</h5>
{{input value=email}}
<h5>Subjects</h5>
{{input type="checkbox" value = "sales" name="sales" checked=sales}}
{{input type="checkbox" value = "support" name="support" checked=support}}
</div>
<button {{action "save"}}> Save </button>
</div>
</script>
EDIT: Here is my current userController.js
App.UserController = Ember.ObjectController.extend({
deleteMode: false,
actions: {
delete: function(){
this.toggleProperty('deleteMode');
},
cancelDelete: function(){
this.set('deleteMode', false);
},
confirmDelete: function(){
// this tells Ember-Data to delete the current user
this.get('model').deleteRecord();
this.get('model').save();
// and then go to the users route
this.transitionToRoute('users');
// set deleteMode back to false
this.set('deleteMode', false);
},
// the edit method remains the same
edit: function(){
this.transitionToRoute('user.edit');
}
}
});
what you need to do is change this line in your template:
{{#each subject in user.subject}}
{{subject.name}},
{{/each}}
for this:
{{#each subject in user.subjects}}
{{subject.name}},
{{/each}}
did you notice I changed subject for subjects ?
and, I would also recommend you to change this code in App.SubjectController:
selected: function() {
var user = this.get('content');
var subject = this.get('parentController.subjects');
return subject.contains(user);
}.property()
to this:
selected: function() {
var subject = this.get('content');
var userSubjects = this.get('parentController.subjects');
return userSubjects.contains(subject);
}.property()
that's a better representation of the data.
I have a model setup with Ember fixtures. My model is like the following:
App.Question = DS.Model.extend({
isCompleted: DS.attr('boolean'),
question_top: DS.attr('string'),
question_bottom: DS.attr('string'),
etc......
});
My fixtures (the actual data) is like the following:
App.Question.FIXTURES = [
{
id: 1
},
{
id: 2
}
];
I want to create a unordered list in my template that shows a "li" item for each record in my Fixtures. I think I need to use the {{#each question}} syntax but when I do {{#each question}}, it doesn't work.
How do I loop through my Fixtures data to create a unordered list, with one list item for each record in my Fixtures data?
Probably your question property doesn't exist in your controller. If you are doing:
App.QuestionRoute = Ember.Route.extend({
model: function() {
return this.store.find('question');
}
});
You can use:
<h2>Questions:</h2>
<ul>
{{#each model}}
<li>{{question_top}}</li>
{{/each}}
</ul>
Give a look in that fiddle http://jsfiddle.net/marciojunior/25GHN/
You need to return it to a route's model hook:
http://emberjs.jsbin.com/UGEmEXEy/1/edit
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('question');
}
});
App.QuestionAdapter = DS.FixtureAdapter;
App.Question = DS.Model.extend({
isCompleted: DS.attr('boolean'),
question_top: DS.attr('string'),
question_bottom: DS.attr('string')
});
App.Question.FIXTURES = [
{
id: 1,
isCompleted: true
},
{
id: 2,
isCompleted: false
}
];
Hi I have been getting investing alot of time in learning Knockout and have come to a point where I have to many properties in my application and I am in need to use the mapping pluggin.
It seems easy enought how it should be used but I mussed be missing something because it does not work.I have created a test example.This is my code:
function vm() {
var self = this;
this.viewModel = {};
this.getData = function() {
$.getJSON('/api/Values/Get').then(data)
.fail(error);
function data(ajaxData) {
console.log(ajaxData);
self.viewModel = ko.mapping.fromJS(ajaxData);
console.log(self.viewModel);
}
function error(jError) {
console.log(jError);
}
};
};
ko.applyBindings(new vm());
This is my html:
<ul data-bind="foreach: viewModel">
<li data-bind="text:FirstName"></li>
<input type="text" data-bind="value: FirstName"/>
</ul>
<button data-bind="click : getData">Press me!</button>
My ajax call succesfully retrieves this data from the server:
[
{
FirstName: "Madalina",
LastName: "Ciobotaru",
hobies: [
"games",
"programming",
"hoby"
]
},
{
FirstName: "Alexandru",
LastName: "Nistor",
hobies: [
"games",
"programming",
"movies"
]
}
]
It seems that after data function is called viewModel get's converted into an array but with no items in it.
What am I doing wrong?
I have taken your expected server data and created a jsfiddle here. You needed to change the viewModel property to be an observable array, and change the way the mapping is performed.
Here is a version of your script that will work:
function vm() {
var self = this;
this.viewModel = ko.observableArray([]);
this.getData = function() {
$.getJSON('/api/Values/Get').then(data)
.fail(error);
function data(ajaxData) {
console.log(ajaxData);
ko.mapping.fromJS(ajaxData, {}, self.viewModel);
console.log(self.viewModel);
}
function error(jError) {
console.log(jError);
}
};
};
ko.applyBindings(new vm());