<commit_before>'use strict';

var Collection = require('ampersand-collection');
var SubCollection = require('ampersand-subcollection');
var React = require('react');
var merge = require('lodash.merge');
var view = require('./view');
var constructCollection = require('../util/ensureInstance').collection;

function bindIfFn(fn, ctx) {
  if (typeof fn === 'function') {
    return fn.bind(ctx);
  }
  return fn;
}

module.exports = function(config) {
  if (config == null) {
    throw new Error('config parameter is required');
  }
  if (config.itemView == null) {
    throw new Error('itemView attribute is required');
  }
  var configCollection = config.collection;
  delete config.collection;

  // items = array of item views
  // collection = ampersand collection
  var CollectionViewMixin = {
    collectionName: 'modelView',
    propTypes: {
      collection: React.PropTypes.oneOfType([
        React.PropTypes.func,
        React.PropTypes.object,
        React.PropTypes.instanceOf(Collection)
      ]),
      data: React.PropTypes.arrayOf(React.PropTypes.object),
      query: React.PropTypes.object,
      offset: React.PropTypes.number,
      limit: React.PropTypes.number,
      where: React.PropTypes.object,
      filter: React.PropTypes.func,
      filters: React.PropTypes.arrayOf(React.PropTypes.func),
      watch: React.PropTypes.arrayOf(React.PropTypes.string),
      sort: React.PropTypes.oneOfType([
        React.PropTypes.string,
        React.PropTypes.func
      ])
    },

    // most options can be passed via config or props
    // props takes precedence
    getDefaultProps: function(){
      return {
        collection: configCollection,
        data: config.data,
        query: config.query,
        offset: config.offset,
        limit: config.limit,
        where: config.where,
        filter: config.filter,
        filters: config.filters,
        watch: config.watch,
        sort: config.sort
      };
    },

    // on component mount we initialize everything
    componentWillMount: function() {
      this._initialize(this.props);
      this._computeItemsWithContext();
    },

    componentWillReceiveProps: function(nextProps) {
      this._configureItems(nextProps);
    },

    componentWillUpdate: function(){
      this._computeItemsWithContext(true);
    },

    _collectionFetchFailed: function(m, res) {
      var notFound = res.status === 404 || res.status === 204;
      var handled404 = notFound && this.collectionNotFound;
      if (this.collectionFetchFailed) {
        this.collectionFetchFailed.apply(this, arguments);
      }
      if (handled404) {
        this.collectionNotFound.apply(this, arguments);
      }

      this.collection = null;
      if (!this.collectionFetchFailed && !handled404) {
        throw new Error('Collection fetch failed with a ' + res.status);
      }
    },

    _initialize: function(props) {
      // get sync and create collection based on model
      // model passed in via props or config
      var collection = constructCollection(props.collection, props);

      var setCollection = (function() {
        this.collection = collection;
        // create items sub-collection
        this._items = new SubCollection(this.collection);<commit_msg>better 0 response error msg<commit_after>'use strict';

var Collection = require('ampersand-collection');
var SubCollection = require('ampersand-subcollection');
var React = require('react');
var merge = require('lodash.merge');
var view = require('./view');
var constructCollection = require('../util/ensureInstance').collection;

function bindIfFn(fn, ctx) {
  if (typeof fn === 'function') {
    return fn.bind(ctx);
  }
  return fn;
}

module.exports = function(config) {
  if (config == null) {
    throw new Error('config parameter is required');
  }
  if (config.itemView == null) {
    throw new Error('itemView attribute is required');
  }
  var configCollection = config.collection;
  delete config.collection;

  // items = array of item views
  // collection = ampersand collection
  var CollectionViewMixin = {
    collectionName: 'modelView',
    propTypes: {
      collection: React.PropTypes.oneOfType([
        React.PropTypes.func,
        React.PropTypes.object,
        React.PropTypes.instanceOf(Collection)
      ]),
      data: React.PropTypes.arrayOf(React.PropTypes.object),
      query: React.PropTypes.object,
      offset: React.PropTypes.number,
      limit: React.PropTypes.number,
      where: React.PropTypes.object,
      filter: React.PropTypes.func,
      filters: React.PropTypes.arrayOf(React.PropTypes.func),
      watch: React.PropTypes.arrayOf(React.PropTypes.string),
      sort: React.PropTypes.oneOfType([
        React.PropTypes.string,
        React.PropTypes.func
      ])
    },

    // most options can be passed via config or props
    // props takes precedence
    getDefaultProps: function(){
      return {
        collection: configCollection,
        data: config.data,
        query: config.query,
        offset: config.offset,
        limit: config.limit,
        where: config.where,
        filter: config.filter,
        filters: config.filters,
        watch: config.watch,
        sort: config.sort
      };
    },

    // on component mount we initialize everything
    componentWillMount: function() {
      this._initialize(this.props);
      this._computeItemsWithContext();
    },

    componentWillReceiveProps: function(nextProps) {
      this._configureItems(nextProps);
    },

    componentWillUpdate: function(){
      this._computeItemsWithContext(true);
    },

    _collectionFetchFailed: function(m, res) {
      var notFound = res.status === 404 || res.status === 204;
      var handled404 = notFound && this.collectionNotFound;
      if (this.collectionFetchFailed) {
        this.collectionFetchFailed.apply(this, arguments);
      }
      if (handled404) {
        this.collectionNotFound.apply(this, arguments);
      }

      this.collection = null;
      if (!this.collectionFetchFailed && !handled404) {
        if (res.status === 0) {
          throw new Error('Collection fetch failed, no response');
        } else {
          throw new Error('Collection fetch failed with a ' + res.status);
        }
      }
    },

    _initialize: function(props) {
      // get sync and create collection based on model
      // model passed in via props or config
      var collection = constructCollection(props.collection, props);

      var setCollection = (function() {
        this.collection = collection;
        // create items sub-collection
        this._items = new SubCollection(this.collection);
{'fraction_non_alphanumeric': 0.11315630657815329, 'fraction_numerical': 0.004828002414001207, 'mean_word_length': 2.79233409610984, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4506570', 'n_tokens_mistral': 1828, 'n_tokens_neox': 1790, 'n_words': 436}