github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/ui/app/adapters/watchable.js (about)

     1  import { get, computed } from '@ember/object';
     2  import { assign } from '@ember/polyfills';
     3  import { inject as service } from '@ember/service';
     4  import queryString from 'npm:query-string';
     5  import ApplicationAdapter from './application';
     6  import { AbortError } from 'ember-data/adapters/errors';
     7  
     8  export default ApplicationAdapter.extend({
     9    watchList: service(),
    10    store: service(),
    11  
    12    xhrs: computed(function() {
    13      return {};
    14    }),
    15  
    16    ajaxOptions(url) {
    17      const ajaxOptions = this._super(...arguments);
    18  
    19      const previousBeforeSend = ajaxOptions.beforeSend;
    20      ajaxOptions.beforeSend = function(jqXHR) {
    21        if (previousBeforeSend) {
    22          previousBeforeSend(...arguments);
    23        }
    24        this.get('xhrs')[url] = jqXHR;
    25        jqXHR.always(() => {
    26          delete this.get('xhrs')[url];
    27        });
    28      };
    29  
    30      return ajaxOptions;
    31    },
    32  
    33    findAll(store, type, sinceToken, snapshotRecordArray, additionalParams = {}) {
    34      const params = assign(this.buildQuery(), additionalParams);
    35      const url = this.urlForFindAll(type.modelName);
    36  
    37      if (get(snapshotRecordArray || {}, 'adapterOptions.watch')) {
    38        params.index = this.get('watchList').getIndexFor(url);
    39        this.cancelFindAll(type.modelName);
    40      }
    41  
    42      return this.ajax(url, 'GET', {
    43        data: params,
    44      });
    45    },
    46  
    47    findRecord(store, type, id, snapshot, additionalParams = {}) {
    48      let [url, params] = this.buildURL(type.modelName, id, snapshot, 'findRecord').split('?');
    49      params = assign(queryString.parse(params) || {}, this.buildQuery(), additionalParams);
    50  
    51      if (get(snapshot || {}, 'adapterOptions.watch')) {
    52        params.index = this.get('watchList').getIndexFor(url);
    53        this.cancelFindRecord(type.modelName, id);
    54      }
    55  
    56      return this.ajax(url, 'GET', {
    57        data: params,
    58      }).catch(error => {
    59        if (error instanceof AbortError) {
    60          return {};
    61        }
    62        throw error;
    63      });
    64    },
    65  
    66    reloadRelationship(model, relationshipName, watch = false) {
    67      const relationship = model.relationshipFor(relationshipName);
    68      if (relationship.kind !== 'belongsTo' && relationship.kind !== 'hasMany') {
    69        throw new Error(
    70          `${relationship.key} must be a belongsTo or hasMany, instead it was ${relationship.kind}`
    71        );
    72      } else {
    73        const url = model[relationship.kind](relationship.key).link();
    74        let params = {};
    75  
    76        if (watch) {
    77          params.index = this.get('watchList').getIndexFor(url);
    78          this.cancelReloadRelationship(model, relationshipName);
    79        }
    80  
    81        if (url.includes('?')) {
    82          params = assign(queryString.parse(url.split('?')[1]), params);
    83        }
    84  
    85        return this.ajax(url, 'GET', {
    86          data: params,
    87        }).then(
    88          json => {
    89            const store = this.get('store');
    90            const normalizeMethod =
    91              relationship.kind === 'belongsTo'
    92                ? 'normalizeFindBelongsToResponse'
    93                : 'normalizeFindHasManyResponse';
    94            const serializer = store.serializerFor(relationship.type);
    95            const modelClass = store.modelFor(relationship.type);
    96            const normalizedData = serializer[normalizeMethod](store, modelClass, json);
    97            store.push(normalizedData);
    98          },
    99          error => {
   100            if (error instanceof AbortError) {
   101              return relationship.kind === 'belongsTo' ? {} : [];
   102            }
   103            throw error;
   104          }
   105        );
   106      }
   107    },
   108  
   109    handleResponse(status, headers, payload, requestData) {
   110      const newIndex = headers['x-nomad-index'];
   111      if (newIndex) {
   112        this.get('watchList').setIndexFor(requestData.url, newIndex);
   113      }
   114  
   115      return this._super(...arguments);
   116    },
   117  
   118    cancelFindRecord(modelName, id) {
   119      const url = this.urlForFindRecord(id, modelName);
   120      const xhr = this.get('xhrs')[url];
   121      if (xhr) {
   122        xhr.abort();
   123      }
   124    },
   125  
   126    cancelFindAll(modelName) {
   127      const xhr = this.get('xhrs')[this.urlForFindAll(modelName)];
   128      if (xhr) {
   129        xhr.abort();
   130      }
   131    },
   132  
   133    cancelReloadRelationship(model, relationshipName) {
   134      const relationship = model.relationshipFor(relationshipName);
   135      if (relationship.kind !== 'belongsTo' && relationship.kind !== 'hasMany') {
   136        throw new Error(
   137          `${relationship.key} must be a belongsTo or hasMany, instead it was ${relationship.kind}`
   138        );
   139      } else {
   140        const url = model[relationship.kind](relationship.key).link();
   141        const xhr = this.get('xhrs')[url];
   142        if (xhr) {
   143          xhr.abort();
   144        }
   145      }
   146    },
   147  });