Reputation: 721
I have a small problem with my ember app, but I still don't know how to solve it..
I have this error :
Error while loading route: TypeError: Object #<Object> has no method 'addArrayObserver'
With this code :
<script type="text/x-handlebars" data-template-name="enquiry">
{{#link-to 'enquiries' class="create-btn"}}Back to the enquiries{{/link-to}}
<div class="enquiry-info">
<button {{action "update"}}>Update</button>
<table>
<tr>
<td>{{enquiry.customerName}}</td>
</tr>
<tr>
<td>{{customerEmail}}</td>
</tr>
<tr>
<td>{{customerPhone}}</td>
</tr>
</table>
</div>
{{outlet}}
</script>
My controller :
App.EnquiriesController = Ember.ArrayController.extend({
actions: {
clickBtn: function( id ) {
console.log('DEBUG: ClickBtn OK id = ' + id);
this.transitionToRoute('enquiry', id);
}
}
});
Router :
App.EnquiryRoute = Ember.Route.extend({
model: function( param ) {
console.log('Enquiry id = ' + param.enquiry_id);
return App.Enquiries.findOne(param.enquiry_id);
}
});
To explain this better, I have a button, and when the user click on it, it trigger the clickBtn function. That return in my router the content of an ajax call from my server.
The thing is that is return me an object and it seems that ember prefer to have an array no ?
Is it possible to display an object in the template instead ?
Here is the ajax call :
findOne: function(id) {
var result = {};
$.ajax({
url: host + 'mdf/enquiry/' + id,
type: 'GET',
accepts: 'application/json',
success: function (data) {
result = data;
},
error: function() {
console.log('DEBUG: GET Enquiry ' + id + ' Failed');
}
});
return result;
}
Thanks for the help !! :)
[edit]
My router map :
App.Router.map(function() {
this.resource('login', { path: '/' });
this.resource('home');
this.resource('enquiries', function (){
this.route('create');
});
this.resource('enquiry', { path: '/:enquiry_id' }, function(){
this.route('update');
});
});
This is the object I've back from the server :
Object {ok: true, enquiry: Object}
enquiry: Object
-createdAt: "2014-02-03T15:32:16.000Z"
-customerEmail: "[email protected]"
-customerName: "Name Test"
-customerPhone: "01523456789"
-id: 1
-__proto__: Object
ok: true
__proto__: Object
Upvotes: 0
Views: 1451
Reputation: 6427
Ember has both ArrayControllers and ObjectControllers. It looks like you need to declare
App.EnquiriesController = Ember.ObjectController.extend({
insted of
App.EnquiriesController = Ember.ArrayController.extend({
EDIT: In response to your edit with more info, I see a couple of issues.
First, and most importantly: Your enquiry
route is a serialized route. As a result, ember will handle the model for this route in a different way than it does other routes.
If you transition to this route by typing in the corresponding URL, the route will behave in a way that rightfully corresponds to your Ember.Route object/model hook. However. If you transition to this route via transitionToRoute('enquiry')
or {{#linkTo 'enquiry'}}
, it will not behave correctly. Your transitions and linkTos should be in format transitionToRoute('enquiry', modelObject)
and {{#linkTo 'enquiry' modelObject}}
, however, it seems you are passing an id
rather than the returned of your ajax call.
So replace:
App.EnquiriesController = Ember.ArrayController.extend({
actions: {
clickBtn: function( id ) {
console.log('DEBUG: ClickBtn OK id = ' + id);
this.transitionToRoute('enquiry', id);
}
}
});
with
App.EnquiriesController = Ember.ArrayController.extend({
actions: {
clickBtn: function( id ) {
console.log('DEBUG: ClickBtn OK id = ' + id);
this.transitionToRoute('enquiry', App.Enquiries.findOne(id));
}
}
});
In addition, on your template, all of your handlebar helpers should be in the format {{enquiry.[propertyName]}}
if you wish to access properties held within the enquiry
object. You did this correctly for customerName
but not for the other 2 properties.
EDIT #2, edit harder:
Additional issues are found.
There's a problem with your Ajax call. The object you return will always be an empty object. That's because ajax calls are asynchronous. You can not rely on an ajax call to run in the order you type it in.
Here's the order that your program is currently running in:
var result = {};
return result;
result = data;
... But we already returned an empty result
in step 3!Because your ajax call is fairly simple and you don't do any transformations on the returned data, I would suggest replacing your findOne
function with:
findOne: function(id) {
return $.ajax({
url: host + 'mdf/enquiry/' + id,
type: 'GET',
accepts: 'application/json',
success: function (data) {
console.log('DEBUG: GET Enquiry ' + id + ' Succeeded');
return data;
},
error: function() {
console.log('DEBUG: GET Enquiry ' + id + ' Failed');
}
});
}
Additionally, in response to your comment about whether you should keep the model hook in your EnquiryRoute: Yes. If a person were to type in the URL associated with that route, then the model hook will trigger (because there will be no modelObject given). If you remove the model hook, the app will only work when clicking links within the app, and will cause errors if you enter the app from a url.
Upvotes: 1