Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Associating custom Adapters with specific models in Ember CLI

We recently made the switch from Ember to Ember CLI and I'm not able to find the proper convention for associating a model with a custom adapter.

History We created an adapter for models that have a file upload as part of their Create route so that form data and binary data could be pushed to one endpoint in our backend api [rails]. The adapter uses the FormData object for adding the file to the request. I opted to only use this adapter for models with files and have non-file upload models use the application adapter. So I would like the ember app to support multiple adapters.

Custom Adapter: in adapters/file-upload.js

import DS from 'ember-data';

var FileUploadAdapter = DS.ActiveModelAdapter.extend({
    ajaxOptions: function(url, type, hash) {
        var self = this;
        hash = hash || {};
        hash.url = url;
        hash.type = type;
        hash.dataType = 'json';
        hash.context = this;

        //add post data to formdata object
        if (hash.data && type != 'GET' && type !='DELETE') {
          hash.processData = false;
          hash.contentType = false;
          var fd = new FormData();
          var root = Object.keys(hash.data)[0];

          for (var i = 0; i < Object.keys(hash.data[root]).length; i++) {
            var key = Object.keys(hash.data[root])[i];
            if (hash.data[root][key]) {
              fd.append(root + "[" + key + "]", hash.data[root][key]);
            }
          }
          hash.data = fd;
        }

        var headers = this.get('headers');
        if (headers) {
          hash.beforeSend = function(xhr){
            for (var i = 0; i < Ember.keys(headers).length; i++) {
              xhr.setRequestHeader(Ember.keys(headers)[i], headers[Ember.keys(headers)[i]]);
            }
          }
        }

        return hash;
    }
});

export default FileUploadAdapter;

In "classic" Ember, I was able to tell ember to use a specific adapter on a model through this convention:

//given a model name "Person", specific adapter via {ModelName}Adapter
App.PersonAdapter = App.FileUploadAdapter.extend();

But now that we don't have these global objects in Ember CLI, is there a way to specify an adapter? I assume that I will want to assign my model to a variable before exporting it and doing additional settings work there.

I desire to fit within the ember cli paradigm, so please let me know if you think this is moving too far away from it. I could go back to using one adapter and doing file detection within it, but separating custom functionality into multiple adapters feels cleaner.

Thanks!

like image 328
William Newby Avatar asked Sep 03 '14 23:09

William Newby


1 Answers

Ember Data uses the resolver to look up adapters. A per-type adapter is looked up via adapter:<type>, so for a Person, this is adapter:person.

ember-cli uses es6 modules and the jj-abrams-resolver to look up these modules based on file names. Usually the lookup is like this: <type>:blah would look for <type>s/blah, so for an adapter:person it will look for adapters/person.

To wire up a PersonAdapter that extends your FileUploadAdapter (located in adapters/file-upload) you can do this:

// adapters/person.js

import FileUploadAdapter from './file-upload';

export default FileUploadAdapter.extend();

You can check the resolver in the console of your app:

// where `App` is the Global name for your app.
var applicationAdapter = App.__container__.lookup('adapter:application');
var personAdapter = App.__container__.lookup('adapter:person');
like image 195
tstirrat Avatar answered Sep 18 '22 15:09

tstirrat