Ember select not binding to a property in the model - ember.js

If I understand the ember.js documentation correctly then I should see the models systemStatus value get populated, but I'm not:
<div class="form-group">
<label class="col-sm-2 control-label" for="name">Description</label>
<div class="col-sm-10">
{{view "select" content=statuses value=model.systemStatus }}
</div>
</div>
This is the controller:
import Ember from "ember";
export default Ember.Controller.extend({
statuses: ["Being Built", "Active","Inactive"],
selectedSystemStatus: 'Active',
actions: {
save: function() {
// this.model.set('systemStatus', this.selectedStatus);
var s = this.get('selectedSystemStatus');
this.model.save();
},
cancel: function() {
}
}
});
The model:
import DS from "ember-data";
export default DS.Model.extend({
name: DS.attr('string', {defaultValue: 'Hello'}),
systemStatus: DS.attr('string', {defaultValue: 'Active'}),
description: DS.attr('string', {defaultValue: 'Describe me'})
});
The router:
import Ember from "ember";
export default Ember.Route.extend({
model: function() {
return this.store.createRecord('software-system');
}
});
Everything works up until you try to select an option from the UI. I'm not sure what I'm doing wrong here, and would like some help.

do you have any place where you call this.store.find('my-model')? This is where the model gets populated.
The default way would be to put it into a corresponding route in the model hook:
// routes/my-model.js
export default Ember.Route.extend({
model: function() {
return this.store.find('my-model');
}
});
With this approach, your controller will wait until the model is loaded.

Related

Why doesn't Ember model update?

My goal is to simply update append a number to an array model. This should create a new HTML element due to the iterator I have used in the template.
My action does get called, but the model doesn't really update.
Here is my directory structure:
- app
- routes
- compare.js
- templates
- compare.hbs
- application.hbs
- app.js
- index.html
- router.js
compare.hbs:
<div id="container">
<form method="post" name="login" {{action "submit" on="submit"}}>
<p>
Member ID
</p>
<p> {{input id="member-id" type="text"}} <input type="submit" value="Search"></p>
</form>
<div id="results">
{{#each model as |result|}}
<p>{{ result }}</p>
{{/each}}
</div>
</div>
router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('compare');
});
export default Router;
compare.js
import Ember from 'ember';
let results = [12, 34, 56];
export default Ember.Route.extend({
model: function() {
return results;
},
actions: {
submit: function() {
results.push(123);
this.get('model').push(123);
this.refresh();
}
}
});
What is the problem?
It looks like you have a few issues. You don't need results.push as that is just adding the value to the array outside of Embers knowledge. When adding to the model use pushObject as that should notify ember of the change. There is also no need to call refresh on the model.
The documentation for pushObject shows an example very similar to what you are attempting:
http://emberjs.com/api/classes/Ember.NativeArray.html#method_pushObject
import Ember from 'ember';
let results = [12, 34, 56];
export default Ember.Route.extend({
model: function() {
return results;
},
actions: {
submit: function() {
this.model().pushObject(123);
}
}
});

Passing a relationship model through link-to helper? ember 2

Heyy!!
I'm having trouble passing a model to a route in ember cli. I'm making a simple app where posts have and author and a title. When you click the title you go to the post details and when you click the author you go to the author's profile. My problem is that I go to the respective user but when I refresh the page I get a n error in the author route. I have no idea why, I'm guessing it has to do with the model not being fetched again when I refresh since it passes the model using link-to helper
My code (client):
app/models/author.js
import DS from 'ember-data';
export default DS.Model.extend({
posts: DS.hasMany('post', {async: true}),
name: DS.attr('string'),
url: DS.attr('string')
});
app/models/post.js
import DS from 'ember-data';
var attr= DS.attr;
export default DS.Model.extend({
author: DS.belongsTo('author'),
title: attr('string'),
description: attr('string'),
date: attr('date'),
url:attr('string'),
});
app/routes/author.js
import Ember from 'ember';
export default Ember.Route.extend({
setupController: function(controller, model) {
model.reload();
controller.set('model', model);}
});
app/templates/posts.hbs
<div class="container" style="width:70%">
{{#each model as |post|}}
<div class="well">
<div class="media">
<a class="pull-left" >
<img class="media-object" src={{post.url}} style="width:200px;height:200px">
</a>
<div class="media-body">
<h1>{{#link-to 'post' post}}{{post.title}}{{/link-to}}</h1>
<h4>Posted by: {{#link-to 'author' post.author.id}} {{post.author.name}}{{/link-to}} </h4>
<p>{{post.description}}</p>
</div>
</div>
</div>
{{/each}}
</div>
My Code (server):
var authors=[];//list of authors
var profileRouter= express.Router();
profileRouter.get('/', function(req, res) {
res.send({
'authors':authors
});
});
profileRouter.get('/:id', function(req, res) {
res.send({
'author': authors.find(function(user){
return author.id==req.params.id
// id: req.params.id,
})
});
});
app.use('/api/author', profileRouter);
You are correct that link-to is passing the model, which is not happening when the page is refreshed. You need to define the model hook on the author route (which is not called when the model is passed) -
model: function(params) {
return this.store.find('author', params.id);
}

Sort model by id

I sideload products of a given category. The problem is that they are not sorted. I'd like to sort them by id and render the sorted products in a select.
How can I sort them?
app/category/model.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
products: DS.hasMany('product', { async: true })
});
route.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return {
category: this.store.find('category', 1)
};
}
});
template.hbs
{{view "select" prompt="All products"
content=model.category.products
optionLabelPath="content.name"
optionValuePath="content.name"
value=selectedProduct
class="form-control"}}
You can use a computed property and the Ember.SortableMixin to sort the products in your controller:
sortedProducts: Ember.computed('model.category.products', function() {
return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
sortProperties: ['id'],
sortAscending: true,
content: this.get('model.category.products')
});
})
And then simply use sortedProducts instead of model.category.products.
Source

Uncaught Error: No model was found for 'model'

I'm building an Ember-CLI app using the following:
DEBUG: Ember : 1.10.0
DEBUG: Ember Data : 1.0.0-beta.15
DEBUG: jQuery : 2.1.3
Using a form, I'm trying to save changes on 2 separate models.
One of the models (the user model) saves successfully, while the other (profile model) throws this error:
Uncaught Error: No model was found for 'userProfile'
Models
The two models in question are:
models/user.js
models/user/profile.js
user model:
import DS from "ember-data";
export default DS.Model.extend({
email: DS.attr('string'),
username: DS.attr('string'),
firstname: DS.attr('string'),
lastname: DS.attr('string'),
comments: DS.hasMany('comments'),
});
profile model:
import DS from "ember-data";
export default DS.Model.extend({
avatar: DS.attr('string'),
educationDegree: DS.attr('string'),
educationUniversity: DS.attr('string'),
workRole: DS.attr('string'),
workOrganisation: DS.attr('string'),
interests: DS.attr('string'),
});
Controller
import Ember from "ember";
export default Ember.Controller.extend({
saved:false,
actions: {
save:function(){
this.get('model.user').save();
this.get('model.profile').save();
this.set('saved',true);
},
},
});
Route
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function(){
var _this = this;
var currentUser = this.get('session.user');
return new Ember.RSVP.all([
_this.store.find('user', currentUser.id),
_this.store.find('user.profile', {UserId: currentUser.id}),
]).then(function(values){
return {
user: values[0],
profile: values[1].get('firstObject'),
}
});
},
});
Template
<form {{action "save" on="submit"}}>
{{input type="text" placeholder="First Name" value=model.user.firstname}}
{{input type="text" placeholder="Last Name" value=model.user.lastname}}
{{input type="email" placeholder="Email" value=model.user.email}}
{{input type="text" placeholder="Affiliation" value=model.profile.workOrganisation}}
<button type="submit" class="btn teal white-text">Save</button>
{{#if saved}}
<p class="text-valid">Save Successful.</p>
{{/if}}
</form>
This error occurs because Ember Data cannot find a model into which to insert the data coming back from the PUT ensuing from the save, which I assume looks like
{ userProfile: { ... } }
I don't know the exact rules by which Ember looks up models based on these "root keys" such as userProfile, but I doubt if it can find the profile model hiding down underneath models/user/.
In the past the following has worked for me, if you have control over the server:
{ "user/profile": { ... } }
If you can't change the server response, or this fails to work for some other reason, the simplest thing to do is to move the profile model up to the top level of the models directory and name it user-profile.js.
Another alternative is to play with modelNameFromPayloadKey:
// serializers/application.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
modelNameFromPayloadKey: function(payloadKey) {
if (payloadKey === 'userProfile') payloadKey = 'user/profile';
return this._super(payloadKey);
}
});

Emberjs how to create a new belongsTo item

I'm working on a simple todo app where each todo item belongs to a user. I'm getting this error:
Uncaught Error: Nothing handled the action 'createTodo'.
I think I'm missing a route and maybe a controller, but I'm not really sure what I need to do.
app/router.js:
import Ember from 'ember';
var Router = Ember.Router.extend({
location: TodoENV.locationType
});
Router.map(function() {
this.route('about');
this.resource('users', function() {
this.route('show', {path: ':user_id'});
});
});
export default Router;
app/routes/users/index.js:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('user');
}
});
app/models/user.js:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
todos: DS.hasMany('todo')
});
app/models/todo.js:
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
user: DS.belongsTo('user')
});
app/controllers/todo.js:
import Ember from 'ember';
export default Ember.ArrayController.extend({
actions: {
createTodo: function() {
var title = this.get('newTitle');
if (!title.trim()) { return; }
var todo = this.store.createRecord('todo', {
title: title // how do I get the user id?
});
this.set('newTitle', '');
todo.save();
}
}
});
app/templates/users/show.hbs:
<h4>{{name}}</h4>
<h5>Todos</h5>
{{input type="text" id="new-todo" placeholder="new todo"
value=newTitle action="createTodo"}}
<ul>
{{#each todos}}
<li>{{title}}</li>
{{/each}}
</ul>
The problem is createTodo is implemented in TodoController whereas you are using createTodo action in users/show template. Action is sent to the UsersShowController where createTodo is not implemented. Move createTodo action into UsersShowController and everything should be OK.