return new $.Deferred().reject(errorResponse).promise();
})
.then(this.__fetchSuccess, this.__fetchFailed);
},
prepare: function() {
var behaviorContext = Behavior.prototype.prepare.apply(this) || {};
behaviorContext.data = this.data.toJSON();
behaviorContext.loading = this.isLoading();
behaviorContext.loadingIds = this.isLoadingIds();
behaviorContext.loadingObjects = this.isLoadingObjects();
return behaviorContext;
},
isLoading: function() {
return this.isLoadingIds() || this.isLoadingObjects();
},
isLoadingIds: function() {
return this.get('loadingIds') > 0;
},
isLoadingObjects: function() {
return this.data.privateCollection.isLoading();
},
listenToIdsPropertyChangeEvent: function() {
if (!_.isUndefined(this.ids.property)) {
this.stopListeningToIdsPropertyChangeEvent();
var idsPropertyNameAndContext = this.__parseIdsPropertyNameAndIdContainer();
var idContainer = idsPropertyNameAndContext.idContainer;
var canListenToEvents = idContainer && _.isFunction(idContainer.on);
if (canListenToEvents) {
this.__currentContextWithListener = idContainer;
this.__currentContextEventName = 'change:' + idsPropertyNameAndContext.idsPropertyName;
this.listenTo(this.__currentContextWithListener, this.__currentContextEventName, this.retrieve);
this.listenTo(this.__currentContextWithListener, 'fetched:ids', this.retrieve);
}
}
},
stopListeningToIdsPropertyChangeEvent: function() {
if (this.__currentContextWithListener) {
this.stopListening(this.__currentContextWithListener, this.__currentContextEventName, this.retrieve);
this.stopListening(this.__currentContextWithListener, 'fetched:ids', this.retrieve);
delete this.__currentContextWithListener;
delete this.__currentContextEventName;
}
},
retrieveOncePromise: function() {
var retrieveOnceDeferred = $.Deferred();
var demographicsFetchSuccess = this.get('fetchSuccess');
if (demographicsFetchSuccess) {
retrieveOnceDeferred.resolve();
} else if (demographicsFetchSuccess === false) {
retrieveOnceDeferred.reject();
} else {
this.once('fetched', function() {
if (this.get('fetchSuccess')) {
retrieveOnceDeferred.resolve();
} else {
retrieveOnceDeferred.reject();
}
});
}
return retrieveOnceDeferred.promise();
},
_delegateUpdateEvents: function() {
this._undelegateUpdateEvents();
var updateEvents = this.__parseUpdateEvents();
_.each(updateEvents, function(parsedUpdateEvent) {
this.listenTo(parsedUpdateEvent.idContainer, parsedUpdateEvent.eventName, this.retrieve);
}, this);
},
_undelegateUpdateEvents: function() {
var updateEvents = this.__parseUpdateEvents();
_.each(updateEvents, function(parsedUpdateEvent) {
this.stopListening(parsedUpdateEvent.idContainer, parsedUpdateEvent.eventName, this.retrieve);
}, this);
},
__parseUpdateEvents: function() {
this.__normalizeAndValidateUpdateEvents();
var updateEvents = _.flatten(_.map(this.updateEvents, this.__parseUpdateEvent, this));
return _.compact(updateEvents);
},
__parseUpdateEvent: function(updateEventConfiguration) {
if (_.isUndefined(updateEventConfiguration)) {
return undefined;
}
var parsedUpdateEvents = [];
if (_.isString(updateEventConfiguration)) {
var updateEvent = this.__parseStringUpdateEvent(updateEventConfiguration);
if (!_.isUndefined(updateEvent)) {
parsedUpdateEvents.push(updateEvent);
}
} else if (_.isObject(updateEventConfiguration)) {
parsedUpdateEvents = _.map(updateEventConfiguration, function(idContainer, eventName) {
return {
idContainer: idContainer,
eventName: eventName
};
});
}
return parsedUpdateEvents;
},
__validateCache: function() {
if (!this.cache) {
throw new Error('Torso Data Behavior constructed without a cache');
}
if (!(this.cache instanceof Collection)) {
throw new Error('Torso Data Behavior\'s cache is not of type Torso.Collection');
}
},
__normalizeAndValidateIds: function() {
if (!_.isUndefined(this.ids) && !_.isUndefined(this.id)) {
throw new Error('Torso Data Behavior constructed with both id and ids. Please define only one.');
}
this.ids = this.id || this.ids;
this.__validateIds();
},
__validateIds: function() {
if (_.isUndefined(this.ids)) {
throw new Error('Torso Data Behavior constructed without a way to identify the ids for this data. Please define either id, ids.');
}
var idsIsArray = _.isArray(this.ids);
var idsIsSingleId = _.isString(this.ids) || _.isNumber(this.ids);
var idsIsFunction = _.isFunction(this.ids);
var idsIsObjectWithStringProperty = _.isString(this.ids.property);
var idsIsObject = _.isObject(this.ids);
var idsIsValid = idsIsArray || idsIsSingleId || idsIsFunction || idsIsObjectWithStringProperty;
if (!idsIsValid && idsIsObject) {
throw new Error('Data Behavior ids invalid definition. It is an object, but the property field is not defined or is not a string: ' + JSON.stringify(this.ids));
} else if (!idsIsValid) {
throw new Error('Data Behavior ids invalid definition. Not a string, number, object, array or function: ' + JSON.stringify(this.ids));
}
if (idsIsObjectWithStringProperty) {
var propertyNameContainsIdContainer = containsContainerDefinition(this.ids.property);
var hasIdContainerProperty = !_.isUndefined(this.ids.idContainer);
if (hasIdContainerProperty && propertyNameContainsIdContainer) {
throw new Error('Data Behavior ids invalid definition. Id container defined on both ids.property and ids.idContainer: ', JSON.stringify(this.ids));
}
}
},
__normalizeAndValidateUpdateEvents: function() {
var updateEventsIsArray = _.isArray(this.updateEvents);
var updateEventsIsSingleValue = !updateEventsIsArray && (_.isObject(this.updateEvents) || _.isString(this.updateEvents));
var updateEventsIsUndefined = _.isUndefined(this.updateEvents);
var updateEventsIsValidType = updateEventsIsArray || updateEventsIsSingleValue || updateEventsIsUndefined;
if (updateEventsIsSingleValue) {
this.updateEvents = [this.updateEvents];
}
if (!updateEventsIsValidType) {
throw new Error('Update events are not an array, string or object. Please see parameters for examples of how to define updateEvents. Configured UpdateEvents: ', this.updateEvents);
}