github.com/manicqin/nomad@v0.9.5/ui/app/adapters/watchable.js (about)

     1  import { get } from '@ember/object';
     2  import { assign } from '@ember/polyfills';
     3  import { inject as service } from '@ember/service';
     4  import queryString from 'query-string';
     5  import ApplicationAdapter from './application';
     6  import { AbortError } from '@ember-data/adapter/error';
     7  
     8  export default ApplicationAdapter.extend({
     9    watchList: service(),
    10    store: service(),
    11  
    12    ajaxOptions(url, type, options) {
    13      const ajaxOptions = this._super(...arguments);
    14      const abortToken = (options || {}).abortToken;
    15      if (abortToken) {
    16        delete options.abortToken;
    17  
    18        const previousBeforeSend = ajaxOptions.beforeSend;
    19        ajaxOptions.beforeSend = function(jqXHR) {
    20          abortToken.capture(jqXHR);
    21          if (previousBeforeSend) {
    22            previousBeforeSend(...arguments);
    23          }
    24        };
    25      }
    26  
    27      return ajaxOptions;
    28    },
    29  
    30    findAll(store, type, sinceToken, snapshotRecordArray, additionalParams = {}) {
    31      const params = assign(this.buildQuery(), additionalParams);
    32      const url = this.urlForFindAll(type.modelName);
    33  
    34      if (get(snapshotRecordArray || {}, 'adapterOptions.watch')) {
    35        params.index = this.watchList.getIndexFor(url);
    36      }
    37  
    38      const abortToken = get(snapshotRecordArray || {}, 'adapterOptions.abortToken');
    39      return this.ajax(url, 'GET', {
    40        abortToken,
    41        data: params,
    42      });
    43    },
    44  
    45    findRecord(store, type, id, snapshot, additionalParams = {}) {
    46      let [url, params] = this.buildURL(type.modelName, id, snapshot, 'findRecord').split('?');
    47      params = assign(queryString.parse(params) || {}, this.buildQuery(), additionalParams);
    48  
    49      if (get(snapshot || {}, 'adapterOptions.watch')) {
    50        params.index = this.watchList.getIndexFor(url);
    51      }
    52  
    53      const abortToken = get(snapshot || {}, 'adapterOptions.abortToken');
    54      return this.ajax(url, 'GET', {
    55        abortToken,
    56        data: params,
    57      }).catch(error => {
    58        if (error instanceof AbortError) {
    59          return;
    60        }
    61        throw error;
    62      });
    63    },
    64  
    65    reloadRelationship(model, relationshipName, options = { watch: false, abortToken: null }) {
    66      const { watch, abortToken } = options;
    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.watchList.getIndexFor(url);
    78        }
    79  
    80        // Avoid duplicating existing query params by passing them to ajax
    81        // in the URL and in options.data
    82        if (url.includes('?')) {
    83          const paramsInUrl = queryString.parse(url.split('?')[1]);
    84          Object.keys(paramsInUrl).forEach(key => {
    85            delete params[key];
    86          });
    87        }
    88  
    89        return this.ajax(url, 'GET', {
    90          abortToken,
    91          data: params,
    92        }).then(
    93          json => {
    94            const store = this.store;
    95            const normalizeMethod =
    96              relationship.kind === 'belongsTo'
    97                ? 'normalizeFindBelongsToResponse'
    98                : 'normalizeFindHasManyResponse';
    99            const serializer = store.serializerFor(relationship.type);
   100            const modelClass = store.modelFor(relationship.type);
   101            const normalizedData = serializer[normalizeMethod](store, modelClass, json);
   102            store.push(normalizedData);
   103          },
   104          error => {
   105            if (error instanceof AbortError) {
   106              return relationship.kind === 'belongsTo' ? {} : [];
   107            }
   108            throw error;
   109          }
   110        );
   111      }
   112    },
   113  
   114    handleResponse(status, headers, payload, requestData) {
   115      // Some browsers lowercase all headers. Others keep them
   116      // case sensitive.
   117      const newIndex = headers['x-nomad-index'] || headers['X-Nomad-Index'];
   118      if (newIndex) {
   119        this.watchList.setIndexFor(requestData.url, newIndex);
   120      }
   121  
   122      return this._super(...arguments);
   123    },
   124  });