brg
brg

Reputation: 3953

How to convert an emberjs Object to JSON in Ember 1.0.0-RC3

I need to pass JSON to jquery-fullcalendar and though I can pass use url as the source from which to fetch the JSON, I would prefer to convert data already loaded into ember-data store to JSON and pass it to fullcalendar, so any changes made on the calendar or on ember would always be in sync.

When I use ember object as the model and create the data in memory,it works as shown here: here. But when I load data via ember-data rest-adapter and try to convert it to JSON using thesame code it fails.

Here is the failing JSfiddle.

When using ember object to create the data I can get it to work by manually creating the json as shown here and pasted below:

When I use Ember object as the model, it generates a valid JSON which accepted by fullcalendar. However, if I change it to to use ember-data model ie, App.Event = DS.Model.extend and change the attributes accordingly to use DS.attr, while the controller remains thesame, it will fail to generate valid json accepted by fullcalendar.

App.Event = Em.Object.extend( {
  title: null,
  start: null,
  allDay: null,

  asJSON: function() {
    return {
        title: this.get('title'),
        start: this.get('start'),
        allDay: this.get('allDay')
    };
  }.property('title', 'start', 'allDay')    

});

The controller that works when using ember object but doesn't when using ember-data

  App.EventsController = Ember.ArrayController.extend({
     content: [
       App.Event.create({
         title: 'event1',
        start: '2013-06-06'
       })
    ],

    contentAsJSON: function() {
        return this.get('content').map(function(event) {
          return event.get('asJSON');
        });
    }.property('content.[]')
 });

This is how I pass the generated JSON from the above model and controller to jquery-fullcalendar. Here the json is recognised by fullcalendar and the events displayed on the calendar. You can see it here.

  App.CalendarView = Em.View.extend({
    templateName: 'calendar',

    didInsertElement: function() {
    this._super();

    var controller = this.get('controller');
    var calendarJSON = controller.eventJSON();
    console.log(calendarJSON);

    this.$().fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        } , 


        editable: true,
       events: calendarJSON
    });
   }
});

How do I do I generate json if i convert the ember-object to ember-data's DS model. So far just swapping out ember object for ember-data is not working.

Update

Working jsfiddle based on the answer by @Gevious.

Adjusted the working code by @Gevious, so it will display only one calendar instead of multiple: The jsfiddle

Final working answer

I moved the didInsertElement and initialization of jquery fullcalendar from the controller back into the views and everything still works the way i want it to.

With Ember-data as datastore: http://jsfiddle.net/C4SD7/5/ and http://jsfiddle.net/C4SD7/3/. With Ember-Model as Data store: http://jsfiddle.net/C4SD7/6/ Beside fullcalendar, here is a link for using datepicker with emberjs: http://jsfiddle.net/jsjyw/3/. Using Momentjs with the calendar: http://jsfiddle.net/M8XLF/7/ and changing the colours of fullcalendar: http://jsfiddle.net/A56LN/43/. Events sideloading appointment using ember-model as datastore: http://jsfiddle.net/duHfN/15/. Thesame code using ember-data as datastore: http://jsfiddle.net/duHfN/14/

Many thanks.

Upvotes: 2

Views: 2415

Answers (1)

Gevious
Gevious

Reputation: 3252

I reproduced your non-working fiddle locally. In the console I get the following error message:

Uncaught Error: assertion failed: an Ember.CollectionView's content must implement Ember.Array.   You passed <(generated appointments controller):ember306> ember-1.0.0-rc.3.js:52
Uncaught Error: assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications. ember-1.0.0-rc.3.js:52

Having had a good look at your code, I suggest you change tact a little. The way you're trying to do things doesn't quit fit ember conventions (IMHO). I recommend you setup a page for appointments and for events as as follows.

App.Router.map(function() {
  this.route('appointments');
  this.route('events');
});

Then in your appointments route you add the model:

App.AppointmentsRoute = Em.Route.extend({
  model: function() return App.Event.model();
});

This way you know you're only dealing with you appointments stack (route/controller/model/view) and can continue debugging. The way you've got the project setup now, there is too much room for error in throwing your different views into your application.

Once you've got the appointments working, you can always use what you have and render the different views as partials inside your application. In this way you will have cleaned up your code and used the ember conventions, while still keeping everything on one page.

Update:

I've put up a fiddle which you can look at for an example of what I mean. The events live under /events and calendar under /calendar. I haven't got the fiddle to work nicely, but if you copy it to your machine you'll see that browsing to events gives you the events, and browsing to calendar gives you the calendar with the events populated.

An aside, I noticed that you didn't include ember data as part of your external js. This could just be that there's no available CDN (I haven't checked), but be sure to include the ember-data.js library in your code. The model and fixtures depend on that library. You can download the latest version from here.

Update 2: Here is a new fiddle. It redirects to the events view, which displays the events and the calendar with all the events present. The calendar should also update as soon as the events update. I had to move the rendering into the controller to make that happen

Upvotes: 2

Related Questions