Error message logged when appending view for global loading state - ember.js

I'm trying to have a default loading view. Following the information here: http://emberjs.com/guides/routing/loading-and-error-substates/#toc_legacy-code-loadingroute-code
LoadingView = Ember.View.extend({
templateName: 'global-loading',
elementId: 'global-loading'
});
ApplicationRoute = Ember.Route.extend({
actions: {
loading: function() {
var view = this.container.lookup('view:loading').append();
this.router.one('didTransition', view, 'destroy');
}
}
});
The view appears to be rendering but I get an error message logged to the console.
Uncaught TypeError: Cannot read property 'get' of null
It looks like it specifically has to do with callind ".append()"
Any idea whats wrong?

Marking this as answered.
It looks like this error was being triggered when the Chrome Ember Inspector was running. After I disabled the extension I didn't see the error message again. I think it was trying to get _debugContainerKey on an object that perhaps didn't have it.

Related

Ember Data createRecord Error on switching routes

I'm getting the following error on createRecord
Uncaught Error: Assertion Failed: You may not pass `null` as id to the store's find method
Create record is called here
var newSchool = this.store.createRecord('deal', {
name: newSchoolName,
timeZone: newTimeZone,
locale: newLanguage,
gradeNames: newGradeNames,
standardSourceIds: newStandardSources,
contentSourceIds: newContentSources,
adminUserId: '511a48a7781200b2cd000001',
numOfToken: 1,
higherEd: higherEd,
dealType: 'institution',
parentDeal: this.get('model.deal')
});
The problem is with the parentDeal it's a belongTo relationship if I change it to null there's no error.
Also the error is only thrown on switching routes and if I log this.get('model.deal') before hand it shows the object.
The model is declared in the route
model: function() {
return Ember.RSVP.hash({
deal: this.store.find('deal', this.get('session.dealId')),
contentSources: this.store.find('contentSource'),
standardSources: this.store.find('standardSource')
});
},
Edit: After kitlers comments
I added the following to deactivate
deactivate: function() {
var model = this.get('model.deal');
if(model && model.get('isDirty')){
model.get('transaction').save()
}
}
Also before hand this is what the store looked like in ember inspector

Ember DS.Errors troubleshooting on create form

I have a basic create form setup which has validation on the name field. The save action for the form has a promise to gracefully hold the error:
actions: {
save: function(){
var route = this;
var createCampaign = this.store.createRecord("campaign", {
code: this.get("code"),
name: this.get("name"),
description: this.get("description"),
});
this.set("code",""),
this.set("name",""),
this.set("description",""),
// POST values to campaigns
createCampaign.save().then(function(c){
route.transitionToRoute("campaigns.view",c.id);
}, function(errors){
});
}
}
});
My defining attributes is:
TM.Campaign = DS.Model.extend({
name: DS.attr(),
code: DS.attr(),
description: DS.attr(),
});
I've read that by using a RESTAdapter, the ajaxError needs to be overwritten, so I've added the following:
ajaxError: function(jqXHR){
var error = this._super(jqXHR);
if(jqXHR && jqXHR.status === 422){
var response = Ember.$.parseJSON(jqXHR.responseText);
errors = {}
if (response.errors){
var jsonErrors = response.errors;
Ember.keys(jsonErrors).forEach(function(key){
errors[Ember.String.camelize(key)] = jsonErrors[key]
});
}
return new DS.InvalidError(errors)
} else {
return error
}
}
The response which is coming from the API is structured as:
{
"errors": {
"name": [
"The name field is required."
]
}
}
But for some reason, whenever I try to display DS.Errors (using console.log(route.get("errors")), I get undefined. It's like Ember doesn't know that a validation error has appeared within the response.
I've also made sure that the response status comes back as 422 Unprocessable Entity. Can anyone see what I'm missing??
EDIT: I have been able to create a JS Bin to demonstrate my problem: http://jsbin.com/xujari/2/
Your jsBin slightly modified :
http://jsbin.com/luwaqeyoca/1/edit?js,console,output
The description of DS.InvalidError never state about setting an error in the route. The sure part is that it sets the promise rejection error. It's also set an error property on the record it self if the property has a property maching the error key name (in breafe if your error key is name you HAVE TO have a property name in your model)
createCampaign.save().then(function(c){
route.transitionToRoute("campaigns.view",c.id);
}, function(errors){
console.log(errors.errors.name); //from the promise error
console.log(createCampaign.get("errors.name")); //from your record
});
EDIT
Here is a bin modified as you asked in comments
http://jsbin.com/sokebuzumu/1/edit?html,js,output
you need to create an empty object "errors" in your controller as in the jsbin
createCampaign.save().then(function(c){
}, function(errors){
this.set("errors",createCampaign.get("errors"));
}.bind(this));
I just answered a similar question on Ember Data Error handling here which covers a number of aspects to error handling related to your question.
You don't need to override the ajaxError handling on the adapter any more since my PR was merged into Ember Data. Errors will be applied to the model correctly now so you can refer to errors using the functions as per my previous answer.

EmberJS 404 Error Handling

I'm dealing with error handling with EmberJS. Now I can handle my errors like this:
App.MediaShowRoute = Ember.Route.extend
...
actions:
error: ()->
#transitionTo '404'
But it is just a temporary decision. What I want to do now, is to render the '404' template within that route, where I get 404 error. For example, if I go to
/media/111111
route and i get an 404 error, I don't want to transition to the 404 page, I want to stay on the same page, but render the 404 template in it. I tried it this way:
actions:
error: () ->
#render '404',
into: 'media.show'
but it is not working :) I will be grateful for your help :)
You'll probably want to look at the ErrorRoute and error template here.
It doesn't exactly handle error codes very well, but when you reject the promise from the model on your App.MediaShowRoute your error will become the content of the ErrorController... You can then check for it in your ErrorRoute#renderTemplate
App.ErrorRoute = Ember.Route.extend({
'renderTemplate' : function() {
switch (this.get('controller.content.code')) {
case 404 : return this.render('404');
default : return this.render();
}
}
});
Take a look at my blog post for a more in depth example of how you might pass the error code around: http://www.riverrockapps.com/post/improving-error-route-in-emberjs

How can I access an Ember input as a jQuery element?

I have a simple form in Ember which submits to a server and returns a response. On a failed response, I want to re-focus on the input field. Is there a way to access the field in my controller using the value binding?
Here's my jsbin as an example:
http://jsbin.com/umodir/1/edit
http://jsbin.com/efatut/2/edit
Your server should return something that sets a property on your controller that you can observe. I made it pretty simple and called it "error".
var App = Ember.Application.create();
App.ApplicationController = Ember.ObjectController.extend({
error: false,
submit: function() {
alert('I want to set a focus on the email input field now...');
this.set('error', true);
}
});
App.ApplicationView = Ember.View.Extend({
focusEmail: function() {
if (this.get('controller.error')) {
this.$('input[type=text]').focus();
}
}.observes('controller.error')
});
If you wanted to get really fancy you could use an Ember.Component like {{eb-input focuson="error"}} that would automatically focus when the controller's "error" property changed.

Attempted to register a view with an id already in use

Since this commit we can't registrer a view with an ID twice. This seems logical. However I got an issue.
Router
App.Router.map(function() {
this.resource('contact', { path: '/contacts/:contact_id' });
});
App.ContactShowRoute = Ember.Route.extend({});
View
App.ContactShowView = Em.View.extend({
elementId: "page-show-contact"
});
Consider that I'm already on the route App.ContactShowRoute. I would like to transitionTo() the same route but with a different context.
I expected emberjs to destroy the view and then create it again, but I got the following error:
Uncaught Error: assertion failed: Attempted to register a view with an id already in use: page-show-contact
I don't want to instantiate a view with the same ID twice. I just want ember to destroy the actual one and then create a new one.
It seems to be a bug in the current version. Maybe you should open a ticket.
Until this is fixed, this might help:
App.ContactShowRoute = Ember.Route.extend({
renderTemplate : function(controller, model) {
if(this.lastRenderedTemplate == this.routeName)
return;
return this._super();
}
});