1

I am building a LWC which shows markers on a map after a user searches for an item. I have tried to create the markers dynamically but I can't seem to get the proper way of doing it.

I have an array that contains the list which is used to search created like this..

//partial code
 pEngage.state = element.State__c;
 pEngage.city = element.City__c;
 pEngage.zip = element.Zip_code__c;
 pEngage.street = element.Street__c;
 
 prepEng.push(pEngage);
 this.searchList =  prepEng;

To search the item..

if(this.num > 0){
  for(var i = 0; i< this.searchResult.length; i++){
    let searchId = this.searchResult[i];
    var index = this.searchIds.findIndex(engId => engId === searchId);                 
    this.finalDisplay = [...this.finalDisplay, this.searchList[index]];
    this.mapArray = [...this.mapArray, this.searchList[index]];
  }
}

So I am now using mapArray to create the mapMarkers which according to the documentation should be created like this..

mapMarkers = [{
    location: {
        Street: '1 Market St',
        City: 'San Francisco',
        Country: 'USA'
    },
    title: 'The Landmark Building',
    description: 'Historic <b>11-story</b> building completed in <i>1916</i>'
}];

My code which is not working..

viewMaps(){
  this.mapVisible =  true;
  
  for(var i = 0; i<this.mapArray.length; i++){
    let markers = [{
      location: {
        Street:this.mapArray[i].street,
        City: this.mapArray[i].city, 
        PostalCode: this.mapArray[i].zip,
        State: this.mapArray[i].state
      },
      description: '<b>Name of Engagement Initiative/Project/Program: </b>' + this.mapArray[i].name
    }];
  
    this.map.splice(i, 0, markers);
  }
  this.mapMarkers = this.map;
  console.log('Map markersy '+ JSON.stringify(this.mapMarkers));
}

The template is checking whether mapMarkers is true.

 <template if:true={mapMarkers}>                                     
                <lightning-map   
                    map-markers={mapMarkers}
                    markers-title="Engagement Distribution"
                    zoom-level={zoomLevel}
                    list-view={listView}>
                    </lightning-map>     
         </template>

I have tried using the spread operator as well as object.assign but they both return a list of lists of objects which cause the error (Cannot read property 'Latitude' of undefined] Failing descriptor: {markup://lightning:map})

Any ideas? Thanks.

The returned object is shown in this imageenter image description here

5
  • please include the code/json from the logs instead of a screenshot
    – glls
    May 13 at 17:19
  • additionally, this error would normally produce itself if you were trying to access the property, however, you don't seem to have included this in your code snippets
    – glls
    May 13 at 17:20
  • It's not clear what you are trying to do. Are you using an array of markers as a reference and building the results from that? So every time there is a search, you want to create a subset for the full list of markers for display? May 14 at 7:13
  • Casper, I have added the template code that is trying to access the markers generated after the search.
    – Pauline
    May 14 at 7:42
  • @glls I am not sure I know what you mean by code from the logs.
    – Pauline
    May 14 at 7:44
0

I still can't really see what you are trying to do. For example - searching on an Id using an exact match - that's not really a search is it?

Because I don't know what you are trying to do, I can't point to the exact problem.

However, I can offer some help in general - which may potentially fix your issue(s)

To search the item, you should be using some sort of Array.prototype method, like Array.forEach or Array.some. Something like this:

searchResult.forEach( searchId => {
  let index = this.searchIds.findIndex(engId => engId === searchId);                 
  this.mapArray = [...this.mapArray, this.searchList[index]];
});

Also, I'm not sure why you are destructuring the mapArray every time. This could get expensive.

Are you trying to keep old results in the array? Also, you could potentially end up with duplicates there - at no point to do you clear that array.

You could just push to an intermediateResults array and write that to the mapArray ouside of the loop.

For the next loop, you should be doing something similar - and you can use the built in Array.prototype.map function to process all the items. I don't see why you need splice here.

Also, you were adding in an Array containing a single Object to the mapMarker array, which would have resulted in an Array[Array[{},{}]] structure - which I don't think will work for you.

Do something like this:

viewMaps(){
  this.mapVisible =  true;
  this.mapMarkers = this.mapArray.map( mapItem => {
    return {
      location: {
        Street:mapItem.street,
        City: mapItem.city, 
        PostalCode: mapItem.zip,
        State: mapItem.state
      },
      description: '<b>Name of Engagement Initiative/Project/Program: </b>' + mapItem.name
    };
  });
}

Also, your template code is looking for the wrong variable:

<template if:true={mapMarkers}>     

I think you meant:

<template if:true={mapVisible}>    

Finally, none of this will really fix the issue unless you have a clear vision of what you are trying to do.

It might be a good idea to sketch out the various data flows and variables so you know what they are going to be doing.

Good luck - you are doing well!

6
  • Thank you so much Casper! You have saved the day! Its working! The arrow function maintained the data structure which is what I needed. I already had the search part working so the code I had shared here was after I got the results which I needed to plot.
    – Pauline
    May 15 at 6:30
  • I am using the mapMakers to control the loading of the map template since I only want it to show after the data is ready.
    – Pauline
    May 15 at 6:34
  • That's great! I wasn't sure it was going to be useful - glad to hear it was! Nice one :) May 15 at 7:14
  • Oh also I forgot to say - you should use the forEach and map functions because they are WAY faster when LockerService is activated (which it is in most circumstances) May 15 at 7:26
  • thanks for the tip Casper. much appreciated. I am actually going to take your advice and modify my search which is using for loops.
    – Pauline
    May 15 at 12:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.