how is possible handle restAdapter errors from store or adapter?
Now I am using this code:
App.ApplicationRoute = Ember.Route.extend({
model: function(){
var self = this;
return this.store.find('item').then(function(data){
return data;
}, function (error){
console.log('error');
return [];
});
},
});
It would be better something more general. Thanks
Until there is some more sophisticated error handling throughout ember data, you could do something like the following to handle network errors in a cross-cutting way:
Extend the RESTAdapter to parse errors from the xhr object
App.ApplicationAdapter = DS.RESTAdapter.extend({
ajaxError: function (jqXHR) {
jqXHR = this._super(jqXHR) || {status : 'unknown'};
var error;
if (jqXHR.status === 404) {
error = 'not_found';
} else if (...) {
...
} else {
error = 'dunno';
}
return error;
}
});
Extend the store to publish error events when bad things happen
App.Store = DS.Store.extend(Ember.Evented, {
recordWasError: function (record, reason) {
this._super.apply(this, arguments);
this.trigger('error', reason);
}
});
Catch the error in your Application Route
App.ApplicationRoute = Ember.Route.extend({
setupController: function () {
this.get('store').on('error', function (error) {
// Do something with the error
console.error(error);
});
},
...
});
Related
I'm trying to set up OAuth with Firebase and Ember. For some reason it's returning the error
Uncaught TypeError: Cannot read property 'login' of undefined
App.LoginController = Ember.ObjectController.extend({
actions: {
login: function() {
var controller = this;
debugger;
controller.get("session").login().then(function(user) {
// Persist your users details.
}, function() {
// User rejected authentication request
});
}
},
});
I was thinking maybe the user is undefined, but I've defined it in a model:
App.User = DS.Model.extend({
username: DS.attr('string'),
});
Then I thought maybe it's the "session" that's undefined--I used the debugger to look up & it says it's an unknown mixin.
var session = Ember.Object.extend({
ref: new Firebase("https://glowing-fire.firebaseio.com/"),
addFirebaseCallback: function() {
var session = this;
this.get("ref").onAuth(function(authData) {
if (authData) {
session.set("isAuthenticated", true);
} else {
session.set("isAuthenticated", false);
}
});
}.on("init"),
login: function() {
return new Promise(function(resolve, reject) {
this.get("ref").authWithOAuthPopup("facebook", function(error, user) {
if (user) {
resolve(user);
} else {
reject(error);
}
});
});
},
currentUser: function() {
return this.get("ref").getAuth();
}.property("isAuthenticated")
});
App.Session = Ember.Object.extend({
initialize: function(container, app) {
app.register("session:main", session);
app.inject("controller", "session", "session:main");
app.inject("route", "session", "session:main");
}
});
I'd really appreciate your help!
The issue might be that you are trying to access an injected property, but the code that does the injection is never called. The recommended way to inject properties is described on this page.
More specifically the samples below (from the Ember.js website) should help
Using an application initializer:
App = Ember.Application.extend();
App.Logger = Ember.Object.extend({
log: function(m) {
console.log(m);
}
});
App.IndexRoute = Ember.Route.extend({
activate: function(){
// The logger property is injected into all routes
this.logger.log('Entered the index route!');
}
});
Ember.Application.initializer({
name: 'logger',
initialize: function(container, application) {
application.register('logger:main', App.Logger);
application.inject('route', 'logger', 'logger:main');
}
});
App.create();
or directly on the application:
App = Ember.Application.create();
App.register('logger:main', {
log: function(m) {
console.log(m);
}
}, { instantiate: false });
App.inject('route', 'logger', 'logger:main');
I'm trying to set a variable in my router from the inside of a promise, but it seems that it is not set properly.
I have create a small example to show you :
App.ApplicationRoute = Ember.Route.extend({
myVar: null,
model: function() {
var data = getData();
console.log(myVar); // = null
return data;
},
getData: function() {
var self = this;
return new Ember.RSVP.Promise( function(resolve, reject) {
self.setProperties({ myVar: 42 });
resolve(someGoodStuff);
reject(someBadStuff)
});
}
})
When I try to display myVar, it still at null even when it was waiting for the promise to resolve...
Do I need to do something special ? or I'm doing it wrongly ?
I believe you are looking for something like this: http://emberjs.jsbin.com/gosoj/3/edit?html,css,js,output
I'm not entirely sure what you are going for here, so there is also some other commented code that may have been your intention.
I think maybe the problem was when you were console logging, as well as the fact that you weren't using your getters and setters properly, and the way you were calling getData()
Here is the code:
App.ApplicationRoute = Ember.Route.extend({
myVar: null,
model: function() {
var data = this.getData();
console.log(data);
console.log(this.get('myVar')); // = null
return data;
},
getData: function() {
var self = this;
return new Ember.RSVP.Promise( function(resolve, reject) {
self.setProperties({ myVar: 42 });
resolve(42);
reject(reason);
}).then(function (value) {
//self.setProperties({ myVar: value });
console.log(self.get('myVar'));
}, function(reason){
console.log(reason);
});
}
})
My server uses sensorID as the primary key on my Sensor model. I've tried the following
App.SensorSerializer = DS.RESTSerializer.extend({
primaryKey: "sensorID"
});
based on what I see in this test, but it's not working. I'm getting an error:
Error while loading route: Error: No model was found for '0'
I'm using a custom adapter. The response is JSONP:
jQuery203041337518650107086_1397489458691([{"sensorID":1,"address":"XXX, YYY","latitude":"nnnn","longitude":"mmmm"...
but when I inspect the data that gets returned, it's a normal array:
// App.SensorAdapter
findAll: function(store, type, sinceToken) {
var url = 'http://blahblahblah/?callback=?';
var query = { since: sinceToken };
return new Ember.RSVP.Promise(function(resolve, reject) {
jQuery.getJSON(url, query).then(function(data) {
debugger;
// data.forEach(function(s) {
// s.id = +s.sensorID;
// });
Ember.run(null, resolve, data);
}, function(jqXHR) {
jqXHR.then = null; // tame jQuery's ill mannered promises
Ember.run(null, reject, jqXHR);
});
});
What is the correct syntax for Ember Data 1.0.0-beta.7?
Try this:
App.Adapter.map('App.Sensor', {
primaryKey: 'sensorID'
});
In soume routes in my app error action is never triggered and I can't figure out why. On some Routes error action works fine.
This is application route:
Simitu.ApplicationRoute = Ember.Route.extend({
init: function() {
this._super();
Simitu.AuthManager = Simitu.AuthManager.create();
},
model: function() {
if (Simitu.AuthManager.get('session.user'))
return this.store.find('admin', Simitu.AuthManager.get('session.user'));
},
actions: {
error: function(reason, transition) {
if (reason.status === 401) {
Simitu.AuthManager.reset();
this.transitionTo('login');
}
}
}
});
On this route Error is never triggered:
Simitu.PlacesIndexRoute = Ember.Route.extend({
model: function() {
var self = this;
// force adapter request
this.store.find('place');
return this.store.filter('place', function(record) {
// return just places that belongs to this client / application
return record.get('client_id') === self.modelFor('client');
});
},
actions: {
createNew: function() {
var place = this.store.createRecord('place');
// tree structure in places is not implemented yet
//parent = this.store.find('place', params.place_id);
place.set('client_id', this.modelFor('client'));
// open place
this.transitionTo('place', place);
},
error: function(error, transition) {
return true;
}
}
});
And on this Route everything works just fine:
Simitu.ClientsRoute = Ember.Route.extend({
model: function() {
return this.store.find('client');
},
actions: {
error: function() {
return true;
}
}
});
Have anybody some ide why?
The error action is fired on the resource, not an individual route.
http://emberjs.jsbin.com/cayidiwa/1/edit
This is how my router looks like. Maybe it breaks because of the nesting or filter logic in models. I fixed it in beforeModel hook in routes but still have not clue what is wrong with my first solution.
Simitu.Router.map(function () {
this.resource('login');
this.resource('clients');
this.resource('client', { path: 'clients/:client_id'}, function() {
this.resource('places', function() {
this.resource('place', { path: ':place_id' });
});
this.resource('placecategories',{ path: 'places-categories' }, function() {
this.route('new');
});
});
});
I move some of auth handling logic to beforeModel hook.
Simitu.AuthRoute = Ember.Route.extend({
beforeModel: function(transition) {
if (!Simitu.AuthManager.isAutenticated()) {
this.redirectToLogin(transition);
}
},
redirectToLogin: function(transition) {
this.transitionTo('login');
},
actions: {
error: function(reason, transition) {
if (reason.status === 401) {
Simitu.AuthManager.reset();
this.redirectToLogin(transoition);
}
}
}
});
Is there any way to handle 500 status error, when creating a new model e.g
var model = this.store.createRecord('user');
model.save().then(function() {
}, function(error) {
// this callback will not be executed if 500 status response
});
However, I can catch it using becameError event on model, but in this case an error object will not be available.
Thanks for your answers.
It looks like a 500 makes it back to the reject route
http://emberjs.jsbin.com/OxIDiVU/159/edit
You can override DS.Model save and assign values from the error hash to your models
App.Model = DS.Model.extend({
save: function() {
var _this = this;
return this._super().then(function(obj) {
return new Ember.RSVP.Promise(function(resolve) {
return resolve(obj);
});
}, function(error) {
//Do something with error here
_this.set('error_status', error.status)
return new Ember.RSVP.Promise(function(resolve, reject) {
return reject(error);
});
});
}
});
Note. becameError event called before error function in save method, so 'error_status' isn't set when becameError called.
var model = this.store.createRecord('user');
model.save().catch(function(error) {
error.status; // status code
});