Steve H.
Steve H.

Reputation: 6947

Adding headers after RESTAdapter initialization

I am trying to add an Authorization header to my adapter's request after the adapter has been initialized and used. I can add headers in a static way at the time I create my ApplicationAdapter, but I can't seem to get it use the headers in subsequent REST calls. I am trying this:

var auth= "Basic " + hash;
App.ApplicationAdapter.reopen({
    headers: {
        Authorization: auth
    }
});

I have debugged RESTAdapter in the ajax method, and the test for adapter.headers is always undefined.

Upvotes: 4

Views: 3794

Answers (3)

Choi Seong Rak
Choi Seong Rak

Reputation: 39

The answers are already introduced in official API document.

http://emberjs.com/api/data/classes/DS.RESTAdapter.html#toc_headers-customization

  • Use computed property with session injection
  • or just use volatile computed property

Upvotes: 1

Rob
Rob

Reputation: 4141

The accepted answer doesn't address the fact that the recommended approach is not working in ember-data. I say recommended since:

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L88

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L162 and other places in that file.

Further, the issue the OP brings up with of undefined specifically happens here: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L619

So, the following simply does not work:

App.ApplicationAdapter.reopen({
  headers: {token: 'reopen_token (NO WORK)' }
});

I've tried to point to this out as an issue but it got closed within an hour: https://github.com/emberjs/data/issues/1820

Hopefully core will decide to either fix this or remove the comments. But, yes, for now it seems you have to hijack jQuery ajax setup, Ember.$.ajaxPrefilter, or override the ajax on the adapter yourself.

EDIT: So after getting some more feedback from Ember devs, it looks like the core of this issue is trying to reopen an instance already created. So using a computered property when it's defined (so it will update as desired) seems to be the advised approach. Hope that helps (there's a recently merged pull request that makes this more obvious in the comments of referenced file:https://github.com/emberjs/data/pull/1818/files#diff-1d7f5a5b77898df15de501c3c38d4829R108 )

EDIT 2: Got this working in my app so here's the code in case someone else gets stuck:

//app.js
App.ApplicationAdapter = DS.ActiveModelAdapter.extend({
  namespace: 'api/v1',
  headers: function() {
    return {
      token: this.get('App.authToken') || localStorage.getItem('token')
    };
  }.property("App.authToken")
});

//login-controller.js (only action shown..assume `data` has user/pass)
  actions: {
    login: function() {
        $.post('/token/', data).done(function(user) {
          App.set('authToken', user.token);
          //Above will trigger adapters's header computed property to update

          // Transition to previous attempted route
          var attemptedTransition = self.get('attemptedTransition');
          if(attemptedTransition) {
            attemptedTransition.retry();
          }
          else {
            self.transitionToRoute('yourapproute');
          }
        })
        .fail(function(response) { 
          //fail handling omitted
        });

Upvotes: 9

Robert Jackson
Robert Jackson

Reputation: 534

You should be able to use $.ajaxPrefilter to add custom headers (or params).

See: http://api.jquery.com/jQuery.ajaxPrefilter/

Ember.$.ajaxPrefilter(function( options, oriOptions, jqXHR ) {
  var auth= "Basic " + hash;
  jqXHR.setRequestHeader("Authorization", auth);
});

Upvotes: 0

Related Questions