Ember Why can't the model data be rendered into template? - templates

So I've been beating my head against this for a few days now. I can't get my model data to render in the template at all. No errors are being thrown. Looking in the Ember Inspector, the Data tab shows my record loaded in tasks.
Any help much appreciated.
// app/adapters/application.js
import Ember from 'ember';
import FirebaseAdapter from 'emberfire/adapters/firebase';
const { inject } = Ember;
export default FirebaseAdapter.extend({
firebase: inject.service(),
});
// app/routes/tasks.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(){
return this.store.findAll('task');
},
});
// app/model/task.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
description:DS.attr('string'),
date: DS.attr('date'),
created: DS.attr('string',{
defaultValue:function(){
return new Date();
}
})
});
// app/templates/tasks.hbs
<h2>tasks</h2>
{{#each task in model}}
<h2>{{task.title}}</h2>
{{/each}}
Ember Inspector:
View Tree:
tasks emtasks/templates/tasks <DS.RecordArray..> tasks --
Data:
task(11)

You are using a newer version of ember. Try this:
// app/templates/tasks.hbs
<h2>tasks</h2>
{{#each model as |task|}}
<h2>{{task.title}}</h2>
{{/each}}

Related

Using and binding JSONAPI attributes data in ember js

I have an ember.js toy application that I want to hook into a JSONAPI REST service for obtaining and displaying data. I can trace in my browser's developer console, that indeed, ember-data initiates the appropriate GET requests and receives proper, valid JSONAPI response bodies.
// ./app/models/person.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
birthdate: DS.attr('string')
});
// ./app/adapters/person.js
import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({
pathForType() {
return "persons";
}
});
// ./app/adapters/application.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
host: 'http://localhost:5000'
});
// ./app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function () {
this.route('persons', function() {
this.route('show', { path: '/:person_id' });
});
});
export default Router;
// ./app/routes/persons/show.js
import Route from '#ember/routing/route';
export default Route.extend({
model(params) {
return this.get('store').findRecord('person', params.person_id);
}
});
// ./app/routes/persons/index.js
import Route from '#ember/routing/route';
export default Route.extend({
model() {
return this.get('store').findAll("person");
}
});
// ./app/routes/application.js
import Route from '#ember/routing/route';
export default Route.extend({
});
// ./app/app.js
import Application from '#ember/application';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
const App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;
// ./app/resolver.js
import Resolver from 'ember-resolver';
export default Resolver;
Unfortunately, when I want to use the model in my template, I can only access the element ids, and not the data attributes like name (Remains empty when rendered).
<!-- ./app/templates/persons/index.hbs -->
{{#each model as |person index|}}
<li>
Person {{person.id}} {{index}}
{{person.name}}
{{#link-to 'persons.show' person }}
Link {{index}}
{{/link-to}}
</li>
{{/each}}
I am a bit at loss for why this happens. Am I doing something wrong?
The posted code is fine, the attributes I was missing in the templates was actually missing from the HTTP responses.

Trying to get data with ember and django rest framework

I have installed Ember Django Adapter(EDA) and I have followed the tutorial and in the template everything is ok but I'm not getting data from my api... but when my model its connect to the api I get the following warning in the console.
WARNING: Encountered "articles" in payload, but no model was found for model name "article" (resolved model name using frontend#serializer:articles:.modelNameFromPayloadKey("articles"))
This is my code:
app/application/serializer.js
import DRFSerializer from '../serializers/drf';
export default DRFSerializer.extend({
});
app/application/adapter.js
import DRFAdapter from '../adapters/drf';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
export default DRFAdapter.extend(DataAdapterMixin , {
authorizer: 'authorizer:django'
});
app/router.js
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('index');
});
export default Router;
app/models/articles.js
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend({
title: attr('string'),
body: attr('string')
});
app/index/route.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.get('store').findAll('articles');
}
});
app/index/template.hbs
{{#each model as |article|}}
<article class="listing">
<h3>{{article.title}}</h3>
</article>
{{/each}}
You should use singular words when naming models, so change your model file to "article.js" and also change in route.js file to this.get('store').findAll('article');

How to populate ember-cli-jstree with model data

I am trying to use this addon to create a tree from my data. I can successfully create a tree from the examples provided in the test/dummy in github, but when I try to use data from a model it seems to be expecting json data and not the ember model.
// models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
children: DS.hasMany('user', {inverse: 'parent', async: true}),
parent: DS.belongsTo('user', {inverse: 'children', async: true})
});
// routes/users.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('user');
}
});
// templates/users.hbs
<h2>Users</h2>
<div class="sample-tree">
{{ember-jstree
data= model
}}
</div>
I have searched for a working example but so far have not found one.
Yes, it expects a plain old JavaScript object in a particular format, not an Ember Data model.
There is an open source working example in Ember Twiddle here: https://github.com/ember-cli/ember-twiddle/blob/7e6739a5fb4c80c454bd173ca93ecbb4f1777250/app/components/file-tree.js#L12

Only show part of template if there exists at least one child-object

I've got a model like this:
import DS from 'ember-data';
var Post = DS.Model.extend({
title: DS.attr('string'),
downloads: DS.hasMany('download')
});
export default Post;
and would like to show the downloads-section only when there is at least 1 or more downloads in the post.
I tried introducing a computed property in the Controller but can't access the model from there.
What else can I do?
EDIT: Here's the controller showing you what I was trying to do:
import Ember from 'ember';
export default Ember.ObjectController.extend({
hasDownloads: function(){
console.log(this.get('downloads')) // <- undefined
return true
}.property('model'),
})
EDIT2: The Object-controller above has no route since it's rendered using `{{render "post"}}. This is an example-template.
<ul class="posts">
{{#with model as post}}
{{render "post"}}
{{/with}}
</ul>
That would be its route:
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.find('post', params).then(function(posts) {
return posts.get('firstObject');
});
}
});
Directly access the property on your controller using model.downloads:
import Ember from 'ember';
export default Ember.ObjectController.extend({
hasDownloads: function(){
console.log(this.get('model.downloads'))
return true
}.property('model.#each'),
})
Depending upon which version of Ember you are using, the proxying behavior of the controller will no longer work. Also, change the property so that it is updated when downloads are added and removed.

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.