+ Start a Discussion
Sumesh ChandranSumesh Chandran 

@track array variable cannot read property push of undefined

I have a track variable which is declared as an array. When I push data to it, I get the error "Cannot read property 'push' of undefined". Also the console.log below get the correct length.
@track cities = [];

  markerClick(e) {
    let province = '';
    getCitiesByProvince({
      province: province,
    }).then(result => {
      console.log(result.length)
      for (let i = 0; i < result.length; i++) {
        this.cities.push(result[i]);
      }
    });
  }

 
Maharajan CMaharajan C
Hi Sumesh,

Post your apex class here. Your JS code looks fine.

May be i think the problem was in result data returned from class is it list or any thing else ? . Because your js trying to access the value from result and then it pushed to array.

Thanks,
Maharajan.C
Sumesh ChandranSumesh Chandran
@Maharajan. The Apex class returns the data as a list and also I was able to print the values of the result variable to the console as well. 
Sumesh ChandranSumesh Chandran
Hello @Maharajan
Please see the code below, I am invoking the markerClick event when the user clicks on the marker inside a map. Could that be a reaon for this error message.
export default class MduPenetration extends LightningElement {

  @track provinces = [];
  @track cities = [];

  @wire(onLoadProvinces) provStats({
    data
  }) {
    if (data) {
      for (let i = 0; i < data.length; i++) {
        this.provinces.push({
          "key": data[i].Id,
          "province": data[i].Name,
          "latitude": latitude,
          "longitude": longitude
        });
      }
      this.initializeMap();
    }
  }

  initializeMap() {
    Promise.allSettled([
      loadStyle(this, leaflet + '/leaflet.css'),
      loadScript(this, leaflet + '/leaflet.js')
    ]).then(() => {
      const el = this.template.querySelector(".map-root");
      let mymap = L.map(el).setView([54.139503, -96.653471], 5);

      L.tileLayer('https://api.mapbox.com/styles/v1/sumchans', { tileSize: 512, zoomOffset: -1 }).addTo(mymap);

      let bcPopup = L.circle([this.provinces[0].latitude, this.provinces[0].longitude], {
        id: 'BC',
        color: 'white',
        fillColor: '#38c',
        fillOpacity: 0.5,
        radius: (this.provinces[0].penetration) * 2500
      }).addTo(mymap).on('click', this.markerClick);
    });
  }
  markerClick(e) {
    getCitiesByProvince({
      province: 'BC'
    }).then(result => {
      if (result) {
        // console.log(this.cities); This says undefined
        for (let i = 0; i < result.length; i++) {
          this.cities.push(result[i]);//This says cannot read push of undefined
        }
      }
    });
  }
}

Please advise!
Sumesh ChandranSumesh Chandran

 
Since it's a callback function, the scope of "this" is changing to the Leaflet library (or possibly a marker class, etc). If you want to maintain the scope of the component, you should use bind to keep the correct scope:
}).addTo(mymap).on('click', this.markerClick.bind(this));
This will make sure you're in the component's scope, and not in the marker's scope.

Sfdcfox helped out on Stackechange. Silly that I didn't put my whole code right at the beginning.


 
Maharajan CMaharajan C
Am posting the Stackexchange link may be it will help someone. 

https://salesforce.stackexchange.com/questions/301692/pushing-to-track-array-variable-says-cannot-read-property-push-of-undefined