All files / addon/utils lazy-select-state.js

0% Statements 0/37
0% Branches 0/11
0% Functions 0/5
0% Lines 0/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94                                                                                                                                                                                           
import { assert } from '@ember/debug';
import { A } from '@ember/array';
import EmberObject, { computed } from '@ember/object';
import { task, didCancel, timeout } from 'ember-concurrency';
 
export default EmberObject.extend({
  lastSearchTerm: undefined,
  resolvedOptions: A([]),
  page: undefined,
  pageCount: undefined,
  isLoading: false,
 
  canLoadMore: computed('page', 'pageCount', function() {
    return this.get('page') < this.get('pageCount');
  }),
 
  initialFetch: task(function * (searchString, searchAction, debounceMS) {
    // Avoid throwing canceled `fetch` sub-task
    try {
      this.set('lastSearchTerm', searchString);
      this.set('page', 1);
 
      yield timeout(debounceMS);
 
      const { options, pageCount } = yield this.get('fetch').perform(searchString, 1, searchAction);
 
      this.set('pageCount', pageCount);
 
      const resolvedOptions = A([]);
 
      if (Array.isArray(options)) {
        resolvedOptions.addObjects(options);
      } else {
        // options is not an array, try to convert to one
        resolvedOptions.addObjects(options.toArray());
      }
 
      this.set('resolvedOptions', resolvedOptions);
 
      return resolvedOptions;
    } catch(e) {
      if (!didCancel(e)) { throw e; }
    }
  }).restartable(),
 
  loadMoreFetch: task(function * (searchString, searchAction) {
    // Avoid throwing canceled `fetch` sub-task
    try {
      const currentPage = this.get('page');
      const nextPage = currentPage + 1;
 
      const { options, pageCount } = yield this.get('fetch').perform(searchString, nextPage, searchAction);
 
      this.set('pageCount', pageCount);
      this.set('page', nextPage);
 
      const resolvedOptions = this.get('resolvedOptions');
 
      if (Array.isArray(options)) {
        resolvedOptions.addObjects(options);
      } else {
        // options is not an array, try to convert to one
        resolvedOptions.addObjects(options.toArray());
      }
 
      return resolvedOptions;
    } catch(e) {
      if (!didCancel(e)) { throw e; }
    }
  }),
 
  fetch: task(function * (searchString, page, searchAction) {
    try {
      this.set('isLoading', true);
 
      return yield searchAction(searchString, page);
    } finally {
      this.set('isLoading', false);
    }
  }).restartable(),
 
  search(term, searchAction, debounceMS = 250) {
    const lastSearchTerm = this.get('lastSearchTerm');
 
    assert('Must pass a search action to `search` on LazySelectState', searchAction);
 
    if (term === lastSearchTerm) {
      return this.get('loadMoreFetch').perform(term, searchAction);
    } else {
      return this.get('initialFetch').perform(term, searchAction, debounceMS);
    }
  },
});