Ember and Yeoman error on edit controller - ember.js

Following this post, on creating an workflow with Yeoman and Ember, when I hit the
/#/story/new url I get this error:
Error while loading route: Getbookmarks.StoryEditRoute<.model#http://localhost:9000/scripts/combined-scripts.js:117
superWrapper#http://localhost:9000/bower_components/ember/ember.js:1230
getModel#http://localhost:9000/bower_components/ember/ember.js:33281
model#http://localhost:9000/bower_components/ember/ember.js:33209
invokeCallback#http://localhost:9000/bower_components/ember/ember.js:9427
publish#http://localhost:9000/bower_components/ember/ember.js:9097
publishFulfillment#http://localhost:9000/bower_components/ember/ember.js:9517
DeferredActionQueues.prototype.flush#http://localhost:9000/bower_components/ember/ember.js:5650
Backburner.prototype.end#http://localhost:9000/bower_components/ember/ember.js:5741
Backburner.prototype.run#http://localhost:9000/bower_components/ember/ember.js:5780
Ember.run#http://localhost:9000/bower_components/ember/ember.js:6181
runInitialize#http://localhost:9000/bower_components/ember/ember.js:38453
jQuery.Callbacks/fire#http://localhost:9000/bower_components/jquery/jquery.js:2913
jQuery.Callbacks/self.fireWith#http://localhost:9000/bower_components/jquery/jquery.js:3025
.ready#http://localhost:9000/bower_components/jquery/jquery.js:398
completed#http://localhost:9000/bower_components/jquery/jquery.js:93
http://localhost:9000/bower_components/ember-data/ember-data.js
Line 3285
The detail of the error is:
error(error=TypeError: this.modelFor(...) is undefined
return this.get('store').find('story', this.modelFor('story').id);
, transition=Object { router={...}, promise=Promise, data={...}, more...}, originRoute=<Getbookmarks.StoryEditRoute:ember265> { routeName="story_edit", router=<Getbookmarks.Router:ember266>, store=<Getbookmarks.Store:ember267>, more...})ember.js (line 33949)
triggerEvent(handlerInfos=[Object { isDynamic=false, name="application", handler=<Getbookmarks.ApplicationRoute:ember268>, more...}, Object { isDynamic=false, name="story_edit", handler=<Getbookmarks.StoryEditRoute:ember265>}], ignoreFailure=true, args=[
TypeError: this.modelFor(...) is undefined
I don't have idea why I getting this. I've followed the tutyorial and I haven't skipped anything. My concerns is that the version of the tutorial is somewhat old, but the code is generated from the ember generator.
Any idea?
EDIT:
this is the generated code for the model:
Getbookmarks.StoryEditRoute = Ember.Route.extend({
model: function(params) {
return this.get('store').find('story', this.modelFor('story').id);
},
setupController: function(controller, model){
controller.set('model', model);
buffer = model.get('attributes').map(function(attr){
return { key: attr.get('key'), value: attr.get('value') }
});
controller.set('buffer', buffer)
}
});
Route:
Getbookmarks.Router.map(function () {
this.resource('index',{path : '/'});
this.resource('story', { path: '/story/:story_id' });
this.resource('story_edit', { path: '/story/new' });
});

I hit the same problem yesterday, following the same guide. This seems to be a problem with the routes, as story edit expects a story_id, which we can't give it for a new story. I managed to solve this problem like this, adding a new route for story_new without the story_id:
in routes.js:
this.resource('story_edit', { path: '/story/edit/:story_id' });
this.resource('story_new', { path: '/story/new' });
Then empty StoryEditController (else the app will complain about the "needs: 'story'", besides it will be replaced later anyway) and add this in routes/story_new_route.js:
Getbookmarks.StoryNewRoute = Ember.Route.extend({
renderTemplate: function() {
var controller = this.controllerFor('storyEdit');
this.render('storyEdit', { controller: controller } );
}
});
This new controller will just redirect to storyEdit controller and use storyEdit-Template. Then empty story_edit_route.js (we'll go with the defaults for now) and you app should run.
Hope this works for you, too, otherwise just tell me and I can give more details.

Related

Go to new item route after creation in Emberjs

I've something like this in my route:
actions: {
save(title, description) {
const newCard = this.get('store').createRecord('card', { title, description } );
newCard.save().then((card) => {
// card.id contains the id of the new card
this.transitionTo('cards.all'); // problem with this line
});
}
}
I want to go to the new card route after creating it. I can get the id of the new item from card.id. I've tried the following but of no use:
this.transitionTo('cards.card', card.id);
This throws some error since the cards.card route can't find the id in the params.
The following:
this.transitionTo('cards/' + card.id);
throws some error stating that cards/45 route not found but if the new item is created and I can navigate to it.
I'm using Ember 2.6.1.
EDIT
My router.js file:
this.route('cards', function() {
this.route('all');
this.route('card', {path: '/:card_id'}, function() {
this.route('edit');
});
this.route('new');
});
Is this what your router currently looks like?
this.route('cards', function() {
this.route('all');
this.route('card', {path: '/:card_id'}, function() {
this.route('edit');
});
this.route('new');
});
If your wanting to go to the new route for a specific card then you would need to define a slug for new. Something like
this.route('new', {path: /:card_id});
The transition in your action hash would like like this:
this.transitionTo('new', card.id);
Hopefully I'm understanding your use case correctly.
It should be this:
this.transitionTo('cards.card', card);
I only needed to do this since my card.js was expecting params object and I was trying to pass a number:
model(params) {
return this.store.find('card', params.id);
}

I am getting Assertion Failed: You must use Ember.set() when Navigate To Route using Href

I am getting the error below when i navigate from my index page to my detail page detail/3.
This works fine when I type detail/3 URL. I am using breeze with ember js
Error: Assertion Failed: You must use Ember.set() to access this property (of [object Object])
App.IndexRoute = Ember.Route.extend({
model: function () {
return EntityQuery.from('Property').using(manager).execute().then(function (data) {
return data.results;
}).fail(queryFailed);
}
});
App.Router.map(function () {
this.route('add');
this.route('detail', {path:'/detail/:detail_id'});
});
App.DetailRoute = Ember.Route.extend({
model: function (params) {
return EntityQuery.from('Property').where("PROPERTY_ID", "==", Number(params.detail_id)).expand('RENTs').using(manager).execute().then(function (data) {
return data.results[0];
}).fail(function (error) {
alert(error);
});
},
serialize: function (model) {
return { detail_id: model.pROPERTY_ID };
}
});
Thanks in advance
Sadly there is no Breeze "model library adapter" for Ember at this time. I hear tell of people who have married Breeze to Ember. You might search for that topic. It's on our wish list but not enough time yet to get it done ourselves.

Error while loading route: undefined while using EmberJS with Firebase (emberFire)

I recreated the TodoMVC using EmberJS and after I was finished, I tried to change the ApplicationAdapter to FirebaseAdapter. But then the application stopped working and I am getting this error:
Error while loading route: undefined
Here are the version I am using
Ember : 1.5.0
Ember Data : 1.0.0-beta.7+canary.b45e23ba
Handlebars : 1.3.0
jQuery : 2.1.0
You can check out the code at github
but here are some of the file contents.
With this code, it works
Todos.ApplicationAdapter = DS.FixtureAdapter.extend();
But when I change it to this, it stops working and I get the error:
Todos.ApplicationAdapter = DS.FirebaseAdapter.extend({
firebase: new Firebase('https://glaring-fire-8506.firebaseio.com')
});
I have the TodosController and TodoController, and this is my router file
Todos.Router.map(function () {
this.resource('todos', { path: '/' }, function () {
this.route('active');
this.route('completed');
});
});
Todos.TodosRoute = Ember.Route.extend({
model: function () {
return this.store.find('todo');
}
});
Todos.TodosIndexRoute = Ember.Route.extend({
model: function () {
return this.modelFor('todos');
},
renderTemplate: function (controller) {
this.render('todos/index', {
controller: controller
});
}
});
Todos.TodosActiveRoute = Todos.TodosIndexRoute.extend({
model: function () {
return this.store.filter('todo', function (todo) {
return !todo.get('isCompleted');
});
}
});
Todos.TodosCompletedRoute = Todos.TodosIndexRoute.extend({
model: function () {
return this.store.filter('todo', function (todo) {
return todo.get('isCompleted');
});
}
});
EDIT: when I added the todos JSON object to Firebase, it's working as it should. But I would really want to understand the problem.
The problem was with the emberFire not handing empty / non-existent collections. This has now been fixed in the emberFire repo.
Github issue: https://github.com/firebase/emberFire/issues/39

Empty controller blocks view. Why?

I have been experimenting with using Ember with a JSON server but without without ember-data. My test app renders a directory of images from a small JSON structure (generated from a little Go server).
Can anyone explain to me why, if I uncomment the App.FileController in the code below, the corresponding File view fails to render?
window.App = Ember.Application.create();
App.Router.map(function() {
this.resource('files',function(){
this.resource('file',{path:':file_id'});
});
});
App.FilesRoute = Ember.Route.extend({
model: function() {
return App.File.findAll();
}
});
App.FileRoute = Ember.Route.extend({
setupController: function(controller, args) {
controller.set('model', App.File.find(args.id));
},
model: function(args) {
return App.File.find(args.file_id);
}
});
App.File = Ember.Object.extend({
urlPath: function(){
return "/pics/" + this.get('id');
}.property('id'),
});
If I uncomment this, things break:
// App.FileController = Ember.Controller.extend({
// });
(namely, the File sub-view no longer renders at all.)
App.File.reopenClass({
find: function(id){
file = App.File.create({'id':id});
return file;
},
findAll: function() {
return $.getJSON("http://localhost:8080/api/").then(
function(response) {
var files = [];
response.Files.forEach(function (filename) {
files.push(App.File.create({'id':filename}));
});
return files;
}
);
},
});
Also, is there something fundamental that I'm doing wrong here?
As noted by Finn MacCool and agmcleod I was trying to use the wrong type of controller. The correct lines should be:
App.FileController = Ember.ObjectController.extend({
});
Not that I need to explicitly set a FileController in this small example. However, should I go on to expand the code I will no doubt need one and will need to use the correct one.

Redirecting to first item in ArrayController

I am trying to redirect to the first item in an ArrayController. I have found a few other questions related to this, but none had answers that seemed to work (a lot of changes have been happening so this is understandable).
One particular answer from Yehuda here:
App.DoctorsRoute = Ember.Route.extend({
model: function() {
return App.Doctor.find();
},
redirect: function() {
var doctor = this.modelFor('doctors').get('firstObject');
this.transitionTo('doctor', doctor);
}
});
I 'think' I have recreated this scenario, but I must have done something wrong...
Any insight into what I am doing wrong is greatly appreciated.
Example JSBin here.
The problem here is that your list of models is not yet loaded from the server. Depending on your needs i would recomend using a promis to let the rout wait abit until your model is loaded.
App.DoctorsRoute = Ember.Route.extend({
model: function() {
return App.Doctor.find().then(function (list) {
return list.get('firstObject');
});
},
redirect: function() {
var doctor = this.modelFor('doctors');
this.transitionTo('doctor', doctor);
}
});
ofcourse.. wel that would make the redirect abit silly, so if you just want to wait for the list to load you could try:
App.DoctorsRoute = Ember.Route.extend({
model: function() {
return App.Doctor.find();
},
redirect: function() {
var self = this;
this.modelFor('doctors').then(function (list) {
return list.get('firstObject');
}).then(function (doctor){
if(!doctor)
self.transitionTo('doctor', doctor);
});
}
});