LoveAndHappiness
LoveAndHappiness

Reputation: 10135

PolymerJS: Iron-Ajax - How to Bind Token to Headers Property?

I have a polymer-element and I want to apply a token as headers attribute.

When I push the button an XMLHttpReqeust is send. The responsible iron-ajax element has a headers property with a string. I would like to change the string, and apply a different attribute.

I've been told that normal compound bindings does not work and I should try computed bindings or just computed properties.

But the problem seems to be the question, how to bind these computed properties or computed bindings to the iron-ajax element?

Whenever I use curly braces, nothing gets evaluated. And if I leave them out, only the remaining string gets parsed.

Here is my element:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">

<dom-module id="demo-element">
    <template>
        <button on-click="sendXMLHttpRequest">sendXMLHttpRequest</button>

        <div>
            Computed Binding HeadersProperty: 
            <span>{{computeHeadersProperty(csrfToken)}}</span>
        </div>
        <div>
            Computed Property HeadersProperty: 
            <span>{{headersProperty}}</span>
        </div>
        <div>
            Computed Binding HeadersToken: 
            <span>{{computeHeadersToken(csrfToken)}}</span>
        </div>
        <div>
            Computed Property HeadersToken: 
            <span>{{headersToken}}</span>
        </div>

        <iron-ajax
             id="ajax"
             method="POST"
             url=""
             handle-as="json"
             headers='{"X-CSRF-Token": "csrfToken"}'
             ></iron-ajax>

    </template>
    <script>
        Polymer({
            is: 'demo-element',

            properties: {
                csrfToken: {
                    type: String,
                    value: 'aBcDeF'
                },
                headersProperty: {
                    type: String,
                    computed: 'computeHeadersProperty(csrfToken)'
                },
                headersToken: {
                    type: String,
                    computed: 'computeHeadersToken(csrfToken)'
                }

            },

            sendXMLHttpRequest: function () {
                // ajax call
                this.$.ajax.body = this.headersProperty;
                this.$.ajax.generateRequest();
            },

            computeHeadersProperty: function (csrfToken) {
                return '{"X-CSRF-Token":\"' + csrfToken + '\"}';
            },

            computeHeadersToken: function (csrfToken) {
                return csrfToken;
            }
        });
    </script>
</dom-module>

As you can see I have created computed bindings and properties for the complete headers property and also just for the token I want to pass in.

But the iron-ajax element does not evaluate anything, when I use curly braces.

Here is what I have tried in the iron-ajax element so far:

  1. headers='{"X-CSRF-Token": "{{csrfToken}}"}' // doesn't evaluate
  2. headers='{"X-CSRF-Token": "{{headersToken}}"}' // doesn't evaluate
  3. headers="{{headersProperty}}" // doesn't evaluate
  4. headers="{{computeHeadersProperty(csrfToken)}}" // doesn't evaluate
  5. headers='{"X-CSRF-Token": "{{computeHeadersToken(csrfToken)}}"}' // doesn't evaluate
  6. headers='{"X-CSRF-Token": "headersToken"}' // evalutes to {"X-CSRF-Token": "headersToken"}
  7. headers='computeHeadersProperty(csrfToken)' // doesn't evaluate

So, how do I have to bind an attribute to the headers property of the iron-ajax element?


EDIT


Some users have have provided a "working solution", which is unfortunately not working, because the headers seem to be set, but it is not included in the headers request. Proof:

Headers Binding Not Working

Compare this to the case when we use a Random String:

Headers String Working

Here the x-csrf-token is properly set.

Because it is not possible to check the request in the provided JSBIN I included a git repository here with the example code: https://github.com/LoveAndHappiness/polymer-iron-ajax-issue-159

I had to include dependencies instead of the polygit resources, because polygit throws errors when working with iron-ajax.


How to reproduce the error?

  1. git clone https://github.com/LoveAndHappiness/polymer-iron-ajax-issue-159.git
  2. Open DevTools and Hit the Request Button. You will see that no headers are set. Change in the iron-ajax element the headers property on line 50 from

headers='{{computeHeadersProperty(csrfToken)}}'

to

headers='{"X-CSRF-Token":"ARandomString"}'

  1. Hit the Request Button again and check in Dev-Tools to see that the token is now accurately set in the headers request.

What I think the error boils down to

Judging by the Output of the Console, the errors seems to be, that the headings property in the iron-ajax element expects an Object, but the evaluation from the databinding returns a string.

I hope somebody can at least reproduce the error.

Upvotes: 3

Views: 4829

Answers (5)

Luka Žitnik
Luka Žitnik

Reputation: 1168

You are probably looking for attribute binding. This will work for you:

    <iron-ajax
         id="ajax"
         method="POST"
         url=""
         handle-as="json"
         headers$='{"X-CSRF-Token": "{{csrfToken}}"}'
         ></iron-ajax>

Upvotes: 1

McPringle
McPringle

Reputation: 2129

The last action on this topic is about half a year ago. I tried the same thing: Adding a token to the header of the iron-ajax request. I tried everything the original poster tried and I tried everything shown in the answers. I searched the net for about three weeks, sometimes several hours each evening. I didn't find a solution. Nothing worked. The properties doesn't evaluate and/or they are not added to the header of the request.

My answer: It looks like it is not possible to add computed properties to the headers of an iron-ajax request yet. Keep in mind that Polymer is a very new framework and a lot of things need to be improved over the next releases.

Upvotes: 1

LoveAndHappiness
LoveAndHappiness

Reputation: 10135

The headersProperty wants to be an Object and not a String.

Working example: http://jsbin.com/rasoqexese/edit?html,output

Many thanks to Peter Burns

Upvotes: 5

Pascal Gula
Pascal Gula

Reputation: 1173

Here is at least a working JSBIN version:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Polymer Bin</title>
    <base href="http://polygit.org/polymer+:master/components/">
    <!-- Third-party imports -->
    <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
    <link href="iron-ajax/iron-ajax.html" rel="import">
    <!-- Styling -->
    <style>
    </style>
    <dom-module id="demo-element">
      <template>
          <button on-click="sendXMLHttpRequest">sendXMLHttpRequest</button>
          <iron-ajax
               id="ajax"
               method="POST"
               url=""
               handle-as="json"
               headers="{{computeHeadersProperty(csrfToken)}}"
               >
          </iron-ajax>
      </template>
    </dom-module>
    <script>
        Polymer({
            is: 'demo-element',

            properties: {
                csrfToken: {
                    type: String,
                    value: 'aBcDeF'
                },
                headersProperty: {
                    type: String,
                    computed: 'computeHeadersProperty(csrfToken)'
                },
                headersToken: {
                    type: String,
                    computed: 'computeHeadersToken(csrfToken)'
                }
            },

            sendXMLHttpRequest: function () {
                // ajax call
                console.log("Headers in AJAX: " + this.$.ajax.headers);
                //this.$.ajax.body = this.headersProperty;
                //this.$.ajax.generateRequest();
            },

            computeHeadersProperty: function (csrfToken) {
                return {"X-CSRF-Token": ' + csrfToken };
            }
        });
    </script>  
  </head>
  <body unresolved class="fullbleed layout vertical">
    <demo-element></demo-element>  
  </body>
</html>

Upvotes: 0

akc42
akc42

Reputation: 5001

I think you need to put notify:true on your csrfToken property.

Upvotes: 0

Related Questions