Using toJSON on a ember.js record, is setting one of the attributes to null

586 views Asked by At

I've been messing with the ember.js todoMVC example. Got it done and working just fine, but to learn some more I started modifying it.

I updated the model from this:

Todos.Todo = DS.Model.extend({
   title: DS.attr('string'),
   isCompleted: DS.attr('boolean'),
});

to this:

Todos.Todo = DS.Model.extend({
    title: DS.attr('string'),
    isCompleted: DS.attr('boolean'),
    date: DS.attr('date')
}); 

(I'm using ember-data as well).

Added to the template to be able to enter a date and then updated the controller action for createTodo to this:

actions: {
    createTodo: function(){
        var title = this.get('newTitle');
        var date = this.get('newDate');     

        if(!title.trim()){
            return;
        }

        var todo = this.store.createRecord('todo',{
            date: date,
            title: title,
            isCompleted: false              
        });

        //this clears the input field value
        this.set('newTitle', '');
        this.set('newDate', '');

        //and save the instance of the model.
        todo.save();
    },
//...More code

Great, all works, so then I'm saving it to localstorage using the localstorage adapter.

This is where things break, the date is not being saved to localstorage, and its because of the toJSON and serialize method which are used in the adapter.

Specifically the adapter does this:

    _addRecordToNamespace: function (namespace, record) {
            var data = record.serialize({includeId: true});
            namespace.records[data.id] = data;
    }

Which takes the _data sub-object that is part of the record, and which looks like so:

//taken from the chrome inspector 
_data: Object
  __ember1386208719445_meta: Meta
  date: "12/11/2013"
  isCompleted: false
  title: "testing something"
  __proto__: Object

and returns:

Object {title: "testing something", isCompleted: false, date: null}

toJSON returns the same thing.

SO TLDR && Question:

Why do the methods toJSON and serialize set my date to null, when it clearly has a value, and that value is a string?

2

There are 2 answers

6
chopper On

Your date format is not valid. Try "2013-02-07T16:44:57" instead of "12/11/2013".

1
Kingpin2k On

It's because you said it was of type date, but you were setting it as a string, so when ember data tried to serialize it it was confused because it expected a date, so it would return null.

serialize: function(date) {
  if (date instanceof Date) {
    var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

    var pad = function(num) {
      return num < 10 ? "0"+num : ""+num;
    };

    var utcYear = date.getUTCFullYear(),
      utcMonth = date.getUTCMonth(),
      utcDayOfMonth = date.getUTCDate(),
      utcDay = date.getUTCDay(),
      utcHours = date.getUTCHours(),
      utcMinutes = date.getUTCMinutes(),
      utcSeconds = date.getUTCSeconds();


    var dayOfWeek = days[utcDay];
    var dayOfMonth = pad(utcDayOfMonth);
    var month = months[utcMonth];

    return dayOfWeek + ", " + dayOfMonth + " " + month + " " + utcYear + " " +
         pad(utcHours) + ":" + pad(utcMinutes) + ":" + pad(utcSeconds) + " GMT";
  } else {
    return null;
  }
}