That should be about right, I think the error is because the this
context is different in your success/error handlers. So in code like this:
save() {
Ember.$.ajax({
url: ENV.host + "/users",
type: "POST",
data: {...},
}).then(() => {
// success handler, 'this' context has changed!
}).catch(function(error) {
// error handler, 'this' no longer points to the controller because the funciton context has changed! And since it has changed it doesn't have a '.set' method like our controller did
});
}
In your success and error handlers you can’t refer to this
the same way that you could in the root of the action, because in the save
action, the context means that the ‘this’ keyword points to the controller, but when you make an ajax request it returns a promise, and then the promise triggers the success or error functions that you pass in, and those have a completely different context. Function context is one of the confusing parts of javascript, especially when it comes to async stuff like this.
So the solution (I’m sure there are others) is to do something like this:
actions: {
save() {
let self = this; // create a new variable called 'self' that points to the current 'this', which is the controller
Ember.$.ajax({
url: ENV.host + "/users",
type: "POST",
data: JSON.stringify({
"user": {
"name": this.get('nameInput'),
"email": this.get('emailInput'), // you're getting this property from the controller now
"password": this.get('passwordInput'),
"password_confirmation": this.get('passwordConfirmationInput'),
}
})
}).then(() => {
// Transition
}).catch(function(error) {
// self points at the OLD definition of 'this', aka the controller, which is what we want
self.set('errorMessage', error.error || error);
});
}
}
For more reading on this I’d recommend reading up on javascript function context and binding and such. It’s a pretty big and confusing topic and can take some time to understand. But in this context, basically anytime you have a promise and are doing something like ‘then’ or ‘catch’ and passing in a function, that function that you pass in will have a different context and you’ll have to do something like the “self” trick above if you want that function to have access to the original context.
EDIT: in the solution, note that you could use either ‘this’ or ‘self’ to get the props from the controller. Since you are constructing the ‘data’ property of the ajax call object in the “root” of the save action, you are still in the correct context. For consistency you could change all of the this.get(...)
calls to self.get(...)