DataStore-DataSource Retrieving Records


The retrieveRecords() method is called on your data source whenever the store needs to retrieve individual records.  This happens most often when the store is trying to follow a toOne() or toMany() relationship or when you call store.find() with a record type and ID.

 

Implementing retrieveRecords() on your data source is usually pretty straightforward.  In fact, you will instead often implement the simpler single-form of the method retrieveRecord().  This method simply needs to lookup the record info and get the correct URL.

 

Retrieving Individual Records

 

The following example shows how you might implement retrieveRecord() for a simple Contact record:

 

AddressBook.DataSource = SC.DataSource.extend({

  // other methods...

 

  retrieveRecord: function(store, storeKey, id) {

 

    // map storeKey back to record type

    var recordType = SC.Store.recordTypeFor(storeKey),

        url;

 

 

    // decide on the URL based on the record type

    if (recordType === AddressBook.Contact) {

      url = “/ab/contacts/%@?alt=json”

    } else {

      // handle other types here...

    }

 

    // if no url is found, we don’t know how to handle this record

    if (!url) return NO;

 

    // we can handle it, get the URL.

    SC.Request.getUrl(url.fmt(id)).set(‘isJSON’, YES)

      .notify(this, this._didRetrieveRecord, {

          store: store,

          storeKey: storeKey

     }).send();

 

    return YES;

  },

 

  _didRetrieveRecord: function(response, params) {

    var store = params.store,

        storeKey = params.storeKey;

 

    // normal: load into store...response == dataHash

    if (SC.$ok(response)) {

      store.dataSourceDidComplete(storeKey, response.get('body'));

 

    // error: indicate as such...response == error

    } else store.dataSourceDidError(storeKey, response.get('body'));

  },

 

  // .. other methods

});

 

Retrieving Records In Bulk

 

The retrieveRecord() API is simple to implement, which makes it convenient.  However, it also initiates a new request to the server for each record you want to retrieve.  Many times, it is better to retrieve records in bulk if you have the API to do so.  To do this, you should override retrieveRecords() on your data source instead of retrieveRecord().

 

The example below implements retrieveRecords() by sorting the list of storeKeys passed into groups based on record type. It then sends one request per record type to the backend:

 

AddressBook.DataSource = SC.DataSource.extend({

  // other methods...

 

  retrieveRecords: function(store, storeKeys) {

 

    // convert storeKeys into id’s sorted by recordType.

    var recordTypes = SC.Set.create(),  // to store record types.

        sortedIds  = {},

        ret=null ; // return value

 

    storeKeys.forEach(function(storeKey) {

      var recordType = SC.Store.recordTypeFor(storeKey);

      recordTypes.add(recordType);

 

      var typeGuid = SC.guidFor(recordType);

      var ids = sortedIds[typeGuid];

      if (!ids) ids = sortedIds[typeGuid] = [];

 

      // map storeKey to ID

      var id = store.idFor(storeKey);

      ids.push(id);

 

    }, this);

 

    // now for each recordType, initiate a request

    recordTypes.forEach(function(recordType) {

 

     // find the URL for the recordType.  if we can’t find one we can’t handle it

     var url;

     if (recordType === AddressBook.Contact) {

       url = "/ab/contacts?alt=json&ids=%@";

      } else {

        // handle other types here...

      }

 

      // if url was found - initiate request

      if (url) {

        var ids = sortedIds[SC.guidFor(recordType)];

        SC.Request.getUrl(url.fmt(ids.join(','))).set('isJSON', YES)

          .notify(this, this._didRetrieveRecords, { store: store, recordType: recordType })

          .send();

 

        // set the proper return value.  

        ret = (ret===NO) ? SC.MIXED_STATE : (ret===null ? YES : ret);  

 

       // if url was not found, set ret to NO or mixed.

       } else ret = (ret === null) ? NO : SC.MIXED_STATE ;

 

     }, this);

     

     return ret;

  },

 

  // called when a group of records have returns. assume result is array of data hashes

  _didRetrieveRecords: function(response, params) {

    var store = params.store,

        recordType = params.recordType;

 

    // normal: load into store...response == dataHash

    if (SC.$ok(response)) {

      store.loadRecords(recordType, response.get('body'));

 

    // error: indicate as such...response == error

    } else store.dataSourceDidError(storeKey, response.get('body'));

  },

 

  // .. other methods

});

 

Moving On

 

On to Committing Changes »

Go back to DataStore Programming Guide Home »