Peter Kelley
Peter Kelley

Reputation: 2360

How do you access object properties from a nested polymer element?

I would like to access javascript object data from a custom polymer element nested inside a list. The host page has the following:

<core-list id="eventData">
    <template>
        <event-card event="{{model}}"></event-card>
    </template>
</core-list>

With the following script:

<script type="text/javascript">
    var data = [
                // server side code to populate the data objects here
            ];
    var theList = document.querySelector('core-list')
    theList.data = data;
    function navigate(event, detail, sender) {
        window.location.href = '/events/show/?eventId=' + event.detail.data.id
    }
    theList.addEventListener("core-activate", navigate, false);
</script>

Inside event-card.html the following markup in the template achieves the desired result:

    <core-toolbar>
        <div class="title">{{event.title}}</div>
    </core-toolbar>
    <div class="responses">{{event.numResponses}} responses</div>

However when I run the following in the template script:

  Polymer('event-card', {
    ready: function() {
        var eventDates = [];
        var theEvent = this.getAttribute('event');
        console.log(theEvent);
        console.log(theEvent.proposedDate);
        console.log(theEvent.possibleStartDate);
        console.log(theEvent.possibleEndDate);
        if (theEvent.proposedDate) {
            eventDates[0] == theEvent.proposedDate;
        } else {
            if (theEvent.possibleStartDate && theEvent.possibleEndDate) {
                var startDate = moment(theEvent.possibleStartDate);
                var endDate = moment(theEvent.possibleEndDate);
                var difference = endDate.diff(startDate, 'days');
                for (i = 0; i < difference; i++) {
                    eventDates[i] = startDate.add(i, days);
                }
            }
        }
        console.log(eventDates);
        this.dates = eventDates;
    },
    created: function() {
        // hint that event is an object
        this.event = {};
    }
  });
</script>

the log statements print

{{model}}
undefined
undefined
undefined
Array[0]

So I seem to be getting caught by the different ways that properties and attributes are evaluated in different contexts but I am not sure whether it is a bug in my code or even what approach to try next.

Upvotes: 0

Views: 1961

Answers (2)

lgersman
lgersman

Reputation: 2286

Because the "event" attribute is set by Polymer when the template is processed, the ready event handler is the wrong place to do your stuff (by the way, using Polymer you should consider using the "domReady" event handler).

Anyway, to get your scenario working, just add a "eventChanged" method to your Polymer component. Whenever an attribute changes (which is also the case when Polymer executes the template element) a "[propertyName]Changed(oldVal, newVal)" will be called (if existing) to signal the change to your component.

So implement this method and you're done.

One more caveat in your code : You should consider using "this.event" to access the attribute value (or as best solution the "newVal" parameter of your eventChanged(oldVal,newVal) method).

Upvotes: 2

flyandi
flyandi

Reputation: 1939

Why not using Polymer's attribution model from the get go?

<polymer-element attributes="event">

<script>
 Polymer("event-card", {

   ready: function() {
     var theEvent = this.event;
   }
 });
</script>

</polymer-element>

Upvotes: 0

Related Questions