Emberjs - adding new record to existing array - ember.js

I'm trying to add a new record to an already existing array of objects.
The form works fine and when I press 'add' on the button, I get the values through.
However, I'm not able to create a new record, I get an error stating
this.init.apply(this, arguments); } has no method 'CreateRecord'".
Thank you for your help.
Here's my code:
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
});
App.AddController = Ember.ObjectController.extend({
content: Ember.Object.create(),
addTo: function(obj){/*
App.Store.createRecord(
App.Post,
{
id: 3,
title: 'Created person',
author: 'dh2',
publishedAt: new Date('12-12-2003')
});*/
alert(JSON.stringify(obj) + "\n" + obj.title);
}
});
App.Post = DS.Model.extend({
title: DS.attr('string'),
author: DS.attr('string'),
publishedAt: DS.attr('date')
});
App.Post.FIXTURES = [
{
id:1,
title: "This is my title",
author: "John Doe",
publishedAt: new Date('12-27-2012')
},
{
id:2,
title: "This is another title",
author: "Jane Doe",
publishedAt: new Date('02-03-2013')
}
];

From inside a controller the store instance of your app is always available because it get's injected in every controller automatically by the framework, so you should access the store like this:
this.get('store').createRecord(App.Post, {...});
This should work correctly and not raise any errors.
Hope it helps.

Related

Trying To Do A Simple Add Item To FIXTURE

I have a simple fixture:
App.User.FIXTURES = [
{ userid: 1, name: 'George', email: 'george#gmail.com', bio: 'Lorem Ipsum', created: 'Jan 5, 2015' },
{ userid: 2, name: 'Tom', email: 'tom#hotmail.com', bio: 'Lorem Ipsum 2', created: 'Jan 15, 2015' },
{ userid: 3, name: 'Mary', email: 'mary#aol.com', bio: 'Lorem Ipsum 3', created: 'Jan 25, 2015' }
];
And I have a simple submit: (snippet)
App.AddController = Ember.ArrayController.extend({
actions: {
save: function () {
App.User.createRecord({ id: 4, userid: 4, name: 'Created person', email: 'sdh', bio: 'my bio', created: '6543456' });
I THINK this is right as I'm not getting an error on createRecord anymore, but now I'm getting an error, any ideas? One more step I'm missing just to shove something into a fixture?
Uncaught TypeError: Object function () {
if (!wasApplied) {
Class.proto(); // prepare prototype...
}
o_defineProperty(this, GUID_KEY, undefinedDescriptor);
o_defineProperty(this, '_super', undefinedDescriptor);
Kingpin2k is correct in that calling createRecord on the UserModel itself is an older way of using Ember Data. If you're using the latest version you should call createRecord from the store object.
Here's what it should look like:
App.AddController = Ember.ArrayController.extend({
actions: {
save: function () {
//Create a new user
var user = this.store.createRecord('user',{
id: 4,
userid: 4,
name: 'Created person',
email: 'sdh',
bio: 'my bio',
created: '6543456'
});
// Saves the new model, but not needed if you're just using FIXTURES
// Making the call shouldn't throw any errors though and is used in the Guide
user.save();
// Now you can find your record in the store
this.store.find('user', 4).then(function(user){
console.info(user);
});
}
}
});
This was tested on:
DEBUG: -------------------------------
DEBUG: Ember : 1.6.0-beta.1+canary.24b19e51
DEBUG: Handlebars : 1.0.0
DEBUG: jQuery : 2.0.2
DEBUG: -------------------------------
I'd recommend reviewing the "Creating a New Model Instance" portion of the Ember getting started guide as they cover this topic there:
http://emberjs.com/guides/getting-started/creating-a-new-model/

Ember: how to show related data (Ember data) in handlebars syntax?

See http://jsfiddle.net/cyclomarc/VXT53/6/
I have data in the form of:
publication: {
id: '1',
title: 'first title',
bodytext: 'first body',
author: {
id: '100',
name: 'Jan'
}
},
I want to show in the hbs part the author name. In the publications hbs (showing each publication), I use the following syntax, but that does not work:
{{publication.author.name}}
In the publications/edit hbs (edit of one publication after selection in publications), I use the following syntax, but that does not work:
{{author.name}}
How should I access the embedded data ?
First of, your working fiddle, sorry I ported it to jsbin since I like it more but this does not affect the functionality in any way: http://jsbin.com/ifukev/2/edit
Now to what I've changed, basically what I've done is to define that a App.Author has many publications and a App.Publication belongs to a App.Author and completed the respective FIXTURES:
App.Author = DS.Model.extend({
name: DS.attr('string'),
publications: DS.hasMany('App.Publication'),
didLoad: function () {
console.log('Author model loaded', this);
}
});
App.Publication = DS.Model.extend({
title: DS.attr('string'),
bodytext: DS.attr('string'),
author: DS.belongsTo('App.Author'),
didLoad: function () {
console.log('Publication model loaded', this);
}
});
//FIXTURES DATA
App.Publication.FIXTURES = [
{
id: '1',
title: 'first title',
bodytext: 'first body',
author: 100
},
{
id: '2',
title: 'second title',
bodytext: 'second post',
author: 300
}
];
App.Author.FIXTURES = [
{
id: '300',
name: 'Marc',
publications: [2]
},
{
id: '100',
name: 'Jan',
publications: [1]
}
];
Hope it helps.

How to dynamically load fixtures in ember.js

Hey I'm having trouble dynamically loading fixture data into my emberjs models. How should I go about doing this? The addArtist function at the bottom will add one song correctly but I'm not sure how to adapt this to loading all of the songs into the data store correctly. Is there an easier way than adding each one individually?
App.Store = DS.Store.extend({
revision: 13,
adapter: 'DS.FixtureAdapter'
});
App.Artist = DS.Model.extend({
name: DS.attr('string'),
tracks: DS.hasMany('App.Tracks')
});
App.Tracks = DS.Model.extend({
videoid: DS.attr('string'),
title: DS.attr('string'),
duration: DS.attr('number')
});
App.Artist.FIXTURES = [];
App.Tracks.FIXTURES = [];
App.loadFixtures = function(){
$.getJSON('/artists', function(data){
$.each(data.artists, function(i,v){
App.Artist.createRecord(v);
});
});
$.getJSON('/tracks', function(data){
$.each(data.tracks, function(i,v){
App.Tracks.createRecord(v);
});
});
};
App.addArtist = function(){
var artist = App.Artist.createRecord({
id: 3,
name: 'Justin Martin'
});
var track = App.Tracks.createRecord({
id: 300,
title: 'Jungle Mix',
duration: 200
});
artist.get('tracks').pushObject(track);
};
Sample JSON Responses:
{"artists":[
{"id":1,"name":"The (International) Noise Conspiracy","track_ids":[1,2,3,4]},
{"id":2,"name":"0SM","track_ids":[5]},
{"id":3,"name":"2am","track_ids":[6,7,8]}
]}
{"tracks":[
{"id":1,"videoid":"FyjmCg_VMU0","title":"Smash It Up","duration":197},
{"id":2,"videoid":"jKXWm9yi4DY","title":"Only Lovers Left Alive","duration":162},
{"id":3,"videoid":"fwbleH55CCk","title":"Up For Sale","duration":211},
{"id":4,"videoid":"50JdKhIB1EQ","title":"A New Morning, Changing Weather","duration":270},
{"id":5,"videoid":"bd6ve0ydHVo","title":"The Landing feat. Alex G - Original Mix","duration":322},
{"id":6,"videoid":"RnwVtbMW4x4","title":"Anxious","duration":238},
{"id":7,"videoid":"Yo0zsqa06ZE","title":"I Did Wrong","duration":305},
{"id":8,"videoid":"_9ydBAgg130","title":"I Love You (feat. Baekchan & Joohee)","duration":219}
]}
Should I include the track_ids in the Artists response or do they get added when I call this method?
artist.get('tracks').pushObject(track);

Unable to query Emberjs Model when using DS.FixtureAdapter

I'm unable to query my models. I don't know what I'm doing wrong.
I have my store defined as
App.Store = DS.Store.extend({
revision: 12,
adapter: DS.FixtureAdapter
});
And my model defined,
var Feature = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
parent: DS.belongsTo('SimpleTestManager.Feature'),
DS.belongsTo('SimpleTestManager.Project'),
children: DS.hasMany('SimpleTestManager.Feature'),
requirements: DS.attr('string')
});
App.Feature.adapter = DS.FixtureAdapter.create();
App.Feature.FIXTURES = [
{
id: 1,
name: "my first feature",
description: "some description",
parent: null,
project: 1,
children:[2],
requirements: "This is my first feature. It has many requirements."
},
{
id: 2,
name: "a sub feature",
description: "some sub feature.",
parent: 1,
project: 1,
children:[],
requirements: "This is a sub feature."
}
];
When I run the following in the command line
>>App.Features.find({id:'1'})
Error: assertion failed: Not implemented: You must override the DS.FixtureAdapter::queryFixtures method to support querying the fixture store.
I managed to solve the mentioned error by using David Lai's answer, but without extending from DS.Store (the new way after Ember Data 1.0.beta.1):
App.FixtureAdapter = DS.FixtureAdapter.extend({
queryFixtures: function(records, query, type) {
return records.filter(function(record) {
for(var key in query) {
if (!query.hasOwnProperty(key)) { continue; }
var value = query[key];
if (record[key] !== value) { return false; }
}
return true;
});
}
});
App.Store = DS.Store.extend({
adapter: 'Fixture'
});
Thanks for your help in trying to figure this out.
From what I've been able to gather, the find() method calls findQuery(), which calls queryFixtures() in the FixturesAdapter. The idea for this not being implemented is for developers to extend this to implement their own find() for stubbing out different search results. For a basic filter on parameter, I was able to just do this.
////// Stub data store fixture adapter ///////
App.Store = DS.Store.extend({
revision: 12,
//adapter: 'DS.RESTAdapter',
adapter: DS.FixtureAdapter.extend({
queryFixtures: function(fixtures, query, type) {
console.log(query);
console.log(type);
return fixtures.filter(function(item) {
for(prop in query) {
if( item[prop] != query[prop]) {
return false;
}
}
return true;
});
}
})
});
I guess your problem is that your are missing the App prefix you have already defined, and also the DS prefix for ember-data. You can also remove Feature.adapter = EmberData.FixtureAdapter.create();.
I've edited your code (not tested).
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
});
App.Feature = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
parent: DS.belongsTo('SimpleTestManager.Feature'),
project:DS.belongsTo('SimpleTestManager.Project'),
children: DS.hasMany('SimpleTestManager.Feature'),
requirements: DS.attr('string')
});
App.Feature.FIXTURES = [
{
id: 1,
name: "my first feature",
description: "some description",
parent: null,
project: 1,
children:[2],
requirements: "This is my first feature. It has many requirements."
},
{
id: 2,
name: "a sub feature",
description: "some sub feature.",
parent: 1,
project: 1,
children:[],
requirements: "This is a sub feature."
}
];
Now to query a specific id you should use:
App.Feature.find(1);
To query by a property you can do:
App.Feature.findQuery({ name: "a sub feature" });
This should work.
Hope it helps
The issue here is that the fixture adapter doesn't actually implement any query methods. If you want to find a record by its ID you can simply call App.Feature.find(id) but anything more complicated than that isn't supported. Even with the DS.RESTAdapter you have to define your own query interface on the server to make queries work properly.

Embedded hasMany attribute access gives "TypeError: Cannot call method 'hasOwnProperty' of undefined"

Using:
Ember commit a5d45f66e1 from Jan 3, 2013)
Ember-Data commit 508479dee7 from Jan 4, 2013
Similar to this question ('Unable to get hasMany association'), I am unable to access embedded hasMany records directly but can see them through the model's content attribute.
For JSON:
{
"ref_book_search":{
"query":"har",
"results":[
{
"publisher":{
"name":"Pangolin",
"created":"2012-09-10T18:38:27.259515",
"id":"3d2028e4fb91181e1a6e012313914f821",
"is_active":true,
"main_url":null,
"resource_uri":"/api/v1/ref_publisher/3d2028e4fb91181e1a6e012313914f821"
},
"genre":"romcom",
"id":"cc671f00fc2711e1e41612313914f821",
"resource_uri":"/api/v1/ref_book/cc671f00fc2711e1e41612313914f821",
"title":"Harry Placeholder and the Goblet of PBR"
},
{
"publisher":{
"name":"Hoof & Mouth",
"created":"2012-10-10T14:31:27.259515",
"id":"3d200e9afb9811e1a27417383914f821",
"is_active":true,
"main_url":null,
"resource_uri":"/api/v1/ref_publisher/3d200e9afb9811e1a27417383914f821"
},
"genre":"horror",
"id":"cc621f08fc2711e1b81612313914e821",
"resource_uri":"/api/v1/ref_book/cc621f08fc2711e1b81612313914e821",
"title":"Harvey Weinstein Holiday Cookbook"
}
]
}
}
And app.js (note the map statements, which were the solution suggested in the prior question):
var App = Ember.Application.create();
DS.RESTAdapter.configure("plurals", {"ref_book_search" : "ref_book_search"});
App.store = DS.Store.create({
revision: 11,
adapter: DS.RESTAdapter.create({
bulkCommits: false,
namespace: "api/v1"
})
});
DS.RESTAdapter.map('App.RefBookSearch', {
primaryKey: 'query'
});
App.store.adapter.serializer.map('App.RefBookSearch', {
results: {embeddded: 'load'}
});
App.store.adapter.serializer.map('App.RefBook', {
publisher: {embeddded: 'load'}
});
App.RefPublisher = DS.Model.extend({
name : DS.attr('string'),
created : DS.attr('date'),
isActive : DS.attr('boolean'),
mainUrl : DS.attr('string')
});
App.RefBook = DS.Model.extend({
publisher: DS.belongsTo('App.RefPublisher'),
title : DS.attr('string'),
genre : DS.attr('string')
});
App.RefBookSearch = DS.Model.extend({
query: DS.attr('string'),
results: DS.hasMany('App.RefBook')
});
App.Router.map(function(match) {
match('/').to('query'),
match('/query/:ref_book_search_id').to('query')
});
App.QueryController = Ember.Controller.extend({
bookSearch: null,
results: []
});
App.QueryRoute = Ember.Route.extend({
setupControllers: function(controller, refBookSearch) {
controller.set('bookSearch', refBookSearch)
controller.set('results', refBookSearch.get('results').content)
}
})
App.initialize();
Everything looks fine at first, just like other poster:
search = App.RefBookSearch.find('ha')
search.get('query')
// => "ha"
results = search.get('results')
results.get('firstObject') instanceof App.RefBook
// => true
But then:
results.forEach(function(result) { console.log(result.get('title')) })
// => TypeError: Cannot call method 'hasOwnProperty' of undefined
Accessing via content shows the data is there:
results.content.forEach(function(result) { console.log(result.title) })
// => Harry Placeholder and the Goblet of PBR
// => Harvey Weinstein Holiday Cookbook
Now if I try accessing directly again, I get a slightly different error:
results.forEach(function(result) { console.log(result.get('title')) })
// => undefined x 2
This may or may not be related to this bug filed a few days ago.
I feel like I've tried everything here; I hope I'm just missing something simple. Any pointers very much appreciated. Thanks.
This is what ultimately worked for me. There seems to be some order-of-operations sensitivity i.e., doing the configure and map before creating the store. Also note that adapter.map is a convenience function that performs the mapping on the serializer.
App.Adapter = DS.RESTAdapter.extend()
App.Adapter.configure("plurals", {
"ref_book_search" : "ref_book_search",
"ref_book" : "ref_book",
"ref_publisher" : "ref_publisher"
});
App.Adapter.configure('App.RefBookSearch', {
primaryKey: 'query'
});
App.Adapter.map('App.RefBookSearch', {
results: {'embedded': 'load'}
});
App.Adapter.map('App.RefBook', {
publisher: {'embedded': 'load'}
});
App.store = DS.Store.create({
revision: 11,
adapter: App.Adapter.create({
bulkCommits: false,
namespace: "api/v1"
})
});