Model from Ember Data not rendering - javascript

I'm trying to figure out how to fetch data with Ember Data and render. After several problems I got to this point where I get no error on the console but the store is empty after the data is loaded.
window.App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
model: function(){
return this.store.find('games');
}
});
App.GamesModel = DS.Model.extend({
name: DS.attr('string')
});
App.GamesAdapter = DS.RESTAdapter.extend({
host: 'http://private-0f6a1-ember37.apiary-mock.com'
});
App.GamesSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload){
var result = { games: payload };
return result;
}
});
And this is the template:
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each model}}
<li>{{name}}</li>
{{/each}}
</ul>
</script>
Here is the link for the code on CodePen: http://codepen.io/tarmann/pen/GJMJxq
I also tried different versions of Ember Data and Ember but with no luck.

Your problem is pluralization: you specify GamesModel instead of GameModel, you find games instead of game etc. I changed all these occurences to be aligned with what Ember expects(and you can read more about Ember standards in guides) and it works, CodePen:
App.IndexRoute = Ember.Route.extend({
model: function(){
return this.store.find('game');
}
});
App.GameModel = DS.Model.extend({
name: DS.attr('string')
});
App.GameAdapter = DS.RESTAdapter.extend({
host: 'http://private-0f6a1-ember37.apiary-mock.com'
});
// https://www.youtube.com/watch?v=HL2bMjndviE
App.GameSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload){
var result = { games: payload };
return result;
}
});
App.IndexController = Ember.Controller.extend({
init: function(){
this.store.push('game', {
id: 100,
name: "Added from controller"
});
}
});
Screenshot with results:

Related

values from model are not updating to the view

I have displayed a textbox using Ember.View.
In model i had specified all the details of the input.
App.Display = DS.Model.extend({
inputText: DS.attr('string'),
width: DS.attr('string'),
height: DS.attr('string'),
className: DS.attr('string')
})
App.Display.FIXTURES = [{
id: '1',
innnerText : 'helo',
width: '197px',
height: '25px',
className: 'DisplayClass'
}]
from the model how can i append the className , width,height and innerText to the display unit.
Here is my displayView
<script type="text/x-handlebars" data-template-name="_display">
{{#view 'App.DisplayView'}}{{/view}}
</script>
App.DisplayView = Ember.View.extend({
tagName: 'input',
});
App.DisplayController = Ember.ArrayController.extend({
actions: {
}
});
How to populate the model data (i.e. innerText,dimensions,className) through controller to the view.
Note:Im not using any this.resource('somename')
In IndexRoute i have set the controller
setupController: function (controller, model) {
controller.set('model', model);
this.controllerFor('Display').set('model', model.displayInput);
In IndexRoute
App.IndexRoute = Ember.Route.extend({
model: function(){
return {
//findall of model name
displayInput : this.store.findAll('display')
}
}
Now to use model to set and get the value of input
Working demo on JS Bin. You're using views - deprecated feature now - instead of components, which make code look not very nice and it's not ideal tool to implement behaviour you want. Instead I converted your approach to use components. Also, in Fixtures you've defined innnerText instead of inputText.
So, let's start with component. Code:
App.DisplayComponentComponent = Ember.Component.extend({
tagName: 'input',
attributeBindings: ['style', 'value'],
style: Ember.computed('model', 'model.{width,height}', function() {
var ret = '',
width = this.get('model.width'),
height = this.get('model.height');
if (width) {
ret += 'width: ' + width + ';';
}
if (height) {
ret += 'height: ' + height + ';';
}
return ret;
})
});
Component template:
<script type="text/x-handlebars" data-template-name="display-component">
</script>
Then, correct fixtures:
App.Display.FIXTURES = [{
id: '1',
inputText : 'helo',
width: '197px',
height: '25px',
className: 'DisplayClass'
}];
There's also a problem with your model. I think it'll be easier to initialize model for display controller just in setupController model.
setupController: function (controller, model) {
controller.set('model', model);
this.store.findAll('display').then(function(displays) {
this.controllerFor('display').set('model', display.get('firstObject'));
});
}
Then, if you want to use it, do it like that(I'm using your example with _display template, but I don't have a clue how do you use this):
<script type="text/x-handlebars" data-template-name="_display">
{{display-component model=model class=model.className value=model.inputText}}
</script>
I have to assume that _display template is for display controller, because you're question isn't clear at all.

Ember.js - cannot createRecord app.mode.createRecord or this.store.createRecord

I created a model with an Ember app, and I'm trying to add a record to the model but I keep getting an error saying undefind is not a function.
window.Aplus = Ember.Application.create();
Aplus.Store = DS.Store.extend();
Aplus.ApplicationAdapter = DS.Adapter.extend({
createRecord: function(store, type, record) {
var data = this.serialize(record, { includeId: true });
var url = type;
return new Ember.RSVP.Promise(function(resolve, reject) {
jQuery.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: data
}).then(function(data) {
Ember.run(null, resolve, data);
}, function(jqXHR) {
jqXHR.then = null; // tame jQuery's ill mannered promises
Ember.run(null, reject, jqXHR);
});
});
}
});
Aplus.Router.map(function () {
this.resource('aplus', function() {
this.route('agents');
});
});
Aplus.Agent = DS.Model.extend({
firstname: DS.attr('string'),
lastname: DS.attr('string'),
team: DS.attr('string'),
position: DS.attr('string'),
email: DS.attr('string'),
});
Aplus.AplusRoute = Ember.Route.extend({
model: function() {
var agentObjects = [];
Ember.$.getJSON('/agents', function(agents) {
console.log(agents);
agents.forEach(function(agent) {
console.log(agent);
console.log(Aplus.Agent.createRecord({
id: 1,
firstname: 'Edmond',
lastname: 'Dantes',
team: 'all',
position:'count',
email: 'count#aplus.com'
}).save());
//agentObjects.pushObject(Aplus.Agent.createRecord(agent));
})
});
return agentObjects;
}
});
The code break on the line where I do Aplus.Agent.createRecord({}). I tried changing it this.store.createRecord({}) and I get an error saying cannot read property createRecord of undefined. The route agents links with my node route and gets the proper data.
Why does this not work? Also why does this.store.createRecord return that store is undefined, I thought it would be defined by extending the DS.Store, and the createRecord would be defined in the extension of applicationAdapter, no?
I thought maybe my links might by old but I use these cdns and I think these are the updated versions
<script src="http://emberjs.com.s3.amazonaws.com/getting-started/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.9.1/ember.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.0.0-beta.14.1/ember-data.min.js"></script>
Any help would be much appreciated.
you lost the context of this inside the getJSON function, make a reference to this before you enter the function var self = this; then call self.store.createRecord({}) instead
Aplus.AplusRoute = Ember.Route.extend({
model: function() {
var agentObjects = [];
var self = this;
Ember.$.getJSON('/agents', function(agents) {
console.log(agents);
agents.forEach(function(agent) {
console.log(agent);
console.log(self.store.createRecord('agent', {
id: 1,
firstname: 'Edmond',
lastname: 'Dantes',
team: 'all',
position:'count',
email: 'count#aplus.com'
}).save());
})
});
return agentObjects;
}
});

Ember: Model as content for CollectionView

How can I add the model data from an ajax request to the content of a Ember.CollectionView so that I can create a list of items? I would like to render a list displaying the title from each object in the array returned from the API. I am using Ember Data as I am trying to learn that along with Ember.
Here is a fiddle to my current code. http://jsfiddle.net/ahzk5pv1/
Here is my JavaScript, Templates, and the data I am returning from an API:
JS:
App = Ember.Application.create();
App.ListView = Ember.CollectionView.extend({
tagName: 'ul',
//How do I set the content to be the data from the API???
content: App.Page,
itemViewClass: Ember.View.extend({
template: Ember.Handlebars.compile('the letter is = {{view.content}}')
})
});
App.ApplicationAdapter = App.RESTAdapter = DS.RESTAdapter.extend({
host: 'https://api.mongolab.com/api/1/databases/embertest2/collections',
//Construct query params for adding apiKey to the ajax url
findQuery: function(store, type, query) {
var url = this.buildURL(type.typeKey),
proc = 'GET',
obj = { data: query },
theFinalQuery = url + "?" + $.param(query);
console.log('url =',url);
console.log('proc =',proc);
console.log('obj =',obj);
console.log('theFinalyQuery =',theFinalQuery);
return this._super(store, type, query);
}
});
App.ApplicationSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload) {
var pagesArray = [];
payload[0].pages.forEach(function(element, index) {
element.id = index;
pagesArray.push(element);
})
return {pages: pagesArray};
}
});
App.Page = DS.Model.extend({
character: DS.attr('string'),
title: DS.attr('string')
});
App.HomeRoute = Ember.Route.extend({
model: function() {
return this.store.find('page', {apiKey: 'somekey'});
}
});
App.Router.map(function() {
this.route('home', {path: '/'});
});
Template:
<script type="text/x-handlebars">
<nav>
{{#link-to 'home'}}Home{{/link-to}}
</nav>
<div class="container">
{{view 'list'}}
</div>
</script>
Data from API:
{
"_id": {
"$oid": "54640c11e4b02a9e534aec27"
},
"start": 0,
"count": 5,
"total": 1549,
"pages": [
{
"character": "Luke Skywalker",
"title": "Star Wars"
},
{
"character": "Sauron",
"title": "Lord Of The Rings"
},
{
"character": "Jean Luc Piccard",
"title": "Star Trek: The Next Generation"
}
]
}
You can use an Ember.ArrayController.
App.items = Ember.ArrayController.create()
App.items.set('content',yourArray)
App.ListView = Ember.CollectionView.extend({
contentBinding: 'App.items'
itemViewClass: Ember.View.extend({
template: Ember.Handlebars.compile('the letter is = {{view.content}}')
})
})
Look at this example
It took some time but this is what I eventually used.
JavaScript:
App = Ember.Application.create();
App.Router.map( function() {
});
App.IndexController = Ember.ArrayController.extend({
});
App.IndexRoute = Ember.Route.extend({
model : function(){
return this.store.find('page', {apiKey: 'keyForApi'});
},
})
App.HomeView = Ember.CollectionView.extend({
tagName: 'ul',
contentBinding: 'controller',
itemViewClass : Ember.View.extend({
tagName : "li",
template : Ember.Handlebars.compile('<p>Name:{{view.content.title}}</p>')
})
});
App.ApplicationAdapter = App.RESTAdapter = DS.RESTAdapter.extend({
host: 'https://api.mongolab.com/api/1/databases/embertest2/collections',
//Construct query params for adding apiKey to the ajax url
findQuery: function(store, type, query) {
var url = this.buildURL(type.typeKey),
proc = 'GET',
obj = { data: query },
theFinalQuery = url + "?" + $.param(query);
console.log('url =',url);
console.log('proc =',proc);
console.log('obj =',obj);
console.log('theFinalyQuery =',theFinalQuery);
return this._super(store, type, query);
}
});
App.ApplicationSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload) {
var pagesArray = [];
payload[0].pages.forEach(function(element, index) {
element.id = index;
pagesArray.push(element);
})
return {pages: pagesArray};
}
});
App.Page = DS.Model.extend({
character: DS.attr('string'),
title: DS.attr('string')
});
Templates:
<script type="text/x-handlebars" data-template-name="application">
<nav>
Example
</nav>
<div class="container">
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="index">
{{view 'home'}}
</script>

Ember handling multiple returns?

I have two json inputs,
Input 1 :
var status = [{
isLogged : true
}];
Input2 :
var posts = [{
id: '1',
datalink:124,
isVoted : true,
votecount : 123,
title: "Rails is Omakase",
author: { name: "d2h" },
date: new Date('12-27-2012'),
excerpt: "There are lots of à la carte software environments in this world. Places where in order to eat, you must first carefully look over the menu of options to order exactly what you want."
}]
Everything worked fine when there was one json,
App.Route = Ember.Route.extend({
model : function(){
return posts;
}
});
But when I added the second input it doesn't work
App.Route = Ember.Route.extend({
model : function(){
return posts;
},
logged : function(){
return status;
}
});
How can I get the second input and disply in the html?
{{#if isLogged}}
<li>Logout</li>
{{else}}
<li>Login</li>
{{/if}}
You need to add the second input into your Route's controller.
App.Route = Ember.Route.extend({
model : function(){
return posts;
},
setupController(controller, model){
controller.set("model", model);
controller.set("isLogged", status);
}
});
And since the isLogged will be declared in the controller, it should be visible within the view.

Refresh view on Ember Data update

I’m doing a very basic application with Ember and Ember Data.
For some reason I always have the same problem. My application renders and displays the data correctly, but if I remove and search, it doesn't update the view.
I’ve already asked this here—the link has more code examples—but with not much luck. Here is how I’m trying to do it:
App = Ember.Application.create({
LOG_TRANSITIONS: true, LOG_VIEW_LOOKUPS: true
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Sample = DS.Model.extend({ name: DS.attr('string') });
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('sample');
}
});
App.IndexController = Ember.ArrayController.extend({
actions: {
remove: function(sample) {
sample.destroyRecord();
}
}
});
App.Sample.FIXTURES = [
{ id: 1, name: 'Learn Ember.js'},
{ id: 2, name: 'Record 2' },
{ id: 3, name: 'Test Delete' }
];
App.ApplicationRoute = Ember.Route.extend({
actions: {
showModal: function(name, content) {
this.controllerFor(name).set('content', content);
this.render(name, {
into: 'application',
outlet: 'modal'
});
},
removeModal: function() {
this.disconnectOutlet({
outlet: 'modal',
parentView: 'application'
});
}
}
});
App.MyModalComponent = Ember.Component.extend({
actions: {
ok: function() {
this.$('.modal').modal('hide');
this.sendAction('ok');
}
},
show: function() {
this.$('.modal').modal().on('hidden.bs.modal', function() {
this.sendAction('close');
}.bind(this));
}.on('didInsertElement')
});
From your code I have tried to come up with a reasonable solution for your problem
Before I get into the solution I think the controller should be IndexController rather than sampleDeleteModalController because ember expects controller to have same name as the route.
App.SampleDeleteModalController = Ember.ObjectController.extend({
actions: {
remove: function() {
// Two ways
this.get('model').destroyRecord();
this.transitionToRoute('index');
}
}
});
transitionToRoute from the same route will not refresh a view.This will work only when you want to redirect to another route.
Solution to refresh view
option 1 : you can capture the same action inside index route after removing the record you can do this.refesh() which refreshes the model.
option 2 : You have to explicitly update the binded model inside the controller.
actions: {
remove: function() {
// Two ways
var localCopy = this.get('model');
localCopy.destroyRecord();
this.set('model',localCopy);
}
}
option 3 : After you set your model your model and then do this.rerender().Which is almost equivalent to window.reload()

Categories

Resources