Dolapo Toki Dolapo Toki - 26 days ago 6
Javascript Question

How to use a callback method to insert data to a polymer property

I have a Polymer page, and I'm trying to push new data to my

my_cart_items
property. If I call
this.AddNewGrocery("data");
in
ready()
, it works; but when I pass that function as a callback in
this.GetGroceryItem("null", "null", this.AddNewGrocery);
, I get this error:

Uncaught TypeError: this.push is not a function(…)


I thought the error had to do with the scope, so I tried accessing the local DOM of the page like this:

//try 1 not Working
Polymer.dom(this.root).querySelector('my-shopview').push('my_cart_items', new CartItem("null","null","Banana1","null","null","null","null"));

//try 2 not Working
document.querySelector('my-shopview').push('my_cart_items', new CartItem("null","null","Banana1","null","null","null","null"));


I'm not sure what else to do. Can anyone please assist me with this?



class CartItem {
constructor(groceryId, groceryImgeUrl, groceryName, groceryOrigin, groceryDescription, grocerSaleDetails, groceryDealDetail, grocerySaleTags, produseTypeTag) {
this.groceryId = groceryId
this.groceryImgeUrl = groceryImgeUrl
this.groceryName = groceryName;
this.groceryOrigin = groceryOrigin;
this.groceryDescription = groceryDescription;
this.grocerSaleDetails = grocerSaleDetails;
this.groceryDealDetail = groceryDealDetail;
this.grocerySaleTags = grocerySaleTags;
this.produseTypeTag = produseTypeTag;
}
}
Polymer({
is: 'my-shopview',
properties: {
my_cart_items: {
type: Object,
value: function() {
return [];
}
}
},
//Querry the database for data
GetGroceryItem: function(querry, count, callback) {
var message = "null";
//querry the database

//callback after we've recived the data
if (callback && typeof callback == "function") {
return callback(message)
}
},
//Callback method to be called after GetGroceryItem has finshed executing
AddNewGrocery: function(post) {
//Working when funciton is called not as a callback method
this.push('my_cart_items', new CartItem("null", "null", "Banana1", "null", "null", "null", "null"));
//Try 1 not Working
//Polymer.dom(this.root).querySelector('my-shopview').push('my_cart_items', new CartItem("null","null","Banana1","null","null","null","null"));
//Try 2 not Working
//document.querySelector('my-shopview').push('my_cart_items', new CartItem("null","null","Banana1","null","null","null","null"));
},
//After local dom has been initiized
ready: function() {
//Populate my cart items with data from firebase
this.push('my_cart_items', new CartItem("null", "null", "Banana2", "null", "null", "null", "null"));
this.push('my_cart_items', new CartItem("null", "null", "Banana3", "null", "null", "null", "null"));
//Get the grocery item's and invove the AddNewGrocery callback method
this.GetGroceryItem("null", "null", this.AddNewGrocery);
}
});





Here's my stack trace for the other 2 approaches:

my-shopview.html:125 Uncaught TypeError: Cannot read property 'push' of null(…)
AddNewGrocery @ my-shopview.html:125
GetGroceryItem @ my-shopview.html:115
ready @ my-shopview.html:133
...

Answer

The problem is you're invoking a callback that requires this to be defined (specifically, this should be the same Polymer object from GetGroceryItem()), in which case you should use Function.prototype.call(this, ...):

callback.call(this, message);

HTMLImports.whenReady(function() {
  Polymer({
    is: 'my-shopview',
    properties: {
      my_cart_items: {
        type: Object,
        value: function() {
          return [];
        }
      }
    },

    GetGroceryItem: function(query, count, callback) {
      var message = "null";

      if (callback && typeof callback == "function") {
        return callback.call(this, message);
      }
    },

    AddNewGrocery: function(post) {
      this.push('my_cart_items', 'Banana1');
    },

    ready: function() {
      this.push('my_cart_items', 'Banana2');
      this.push('my_cart_items', 'Banana3');
      this.GetGroceryItem("null", "null", this.AddNewGrocery);
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <my-shopview></my-shopview>

  <dom-module id="my-shopview">
    <template>
      <template is="dom-repeat" items="[[my_cart_items]]">
        <div>[[item]]</div>
      </template>
    </template>
  </dom-module>
</body>

codepen