I'm trying the new lightning:map tag from the winter 19 and i'm having some issue.
I achieve to display a simple map filled with a list of objects. They are shown as markers on the map and also on a sidebar generate by the lightning:tag too (the "showFooter" parameter).
Problems :
1) When i'm changing the list, changes appear on the sidebar but markers on the map don't change (none appears or disappears).
2) When i have a list of 1 or less markers to show, the sidebar desapears. But if after i reset the list to 2 or more, the sidebar doesn't reappear.
I did a simplified code that show the problem :
component :
<aura:component>
<!-- attributes -->
<aura:attribute name="mapMarkers" type="Object"/>
<aura:attribute name="markersTitle" type="String" />
<aura:attribute name="showFooter" type="Boolean" />
<aura:attribute name="center" type="Object" />
<aura:attribute name="zoomLevel" type="Integer" />
<!-- initialize map and "simulate" checkbox as clicked to fill the list -->
<aura:handler name="init" value="{! this }" action="{! c.init }"/>
<aura:handler name="init" value="{! this }" action="{! c.checkboxChanged }"/>
<div>
<lightning:input type="checkbox" name="checkbox" label="Change" aura:id="checkbox" onchange="{!c.checkboxChanged}"/>
<lightning:button label="Clear" onclick="{!c.clear}"/>
<lightning:map
mapMarkers="{! v.mapMarkers }"
center="{! v.center }"
zoomLevel="{! v.zoomLevel }"
markersTitle="{! v.markersTitle }"
showFooter="{ !v.showFooter }" >
</lightning:map>
</div>
</aura:component>
Controller :
({
init : function(component, event, helper)
{
//initialize the map
component.set('v.center', {
location: {
City: 'Fréjus'
}
});
component.set('v.zoomLevel', 9);
component.set('v.markersTitle', 'Some people');
component.set('v.showFooter', true);
},
checkboxChanged : function(component, event, helper)
{
//swap between two lists of markers
var check = component.find('checkbox').get('v.checked')
if(check == true) //list 1
{
component.set("v.mapMarkers", [
{
location: {
City: 'Cap-d\'Ail',
Country: 'France',
},
icon: 'custom:custom26',
title: 'Cap-d\'Ail'
},
{
location: {
City: 'Beaulieu-sur-Mer',
Country: 'France',
},
icon: 'custom:custom96',
title: 'Beaulieu-sur-Mer'
}]);
}
else //list 2
{
component.set("v.mapMarkers", [{
location: {
City: 'Fréjus',
Country: 'France',
},
icon: 'custom:custom88',
title: 'Fréjus'
},
{
location: {
City: 'Sainte-Maxime',
Country: 'France',
},
icon: 'custom:custom92',
title: 'Sainte-Maxime'
},
{
location: {
City: 'Saint-Tropez',
Country: 'France',
},
icon: 'custom:custom26',
title: 'Saint-Tropez'
}
]);
}
},
clear : function(component, event, helper)
{
//clear the current list showed
component.set("v.mapMarkers", new Array());
}
})
I know it's early to have much information about it, but this tag is really interesting.
Thanks for any help !
Best Answer
I tried out the
lightning:map
too and I had the same issue: it wouldn't re-render no matter what I did. It's an issue with the map itself, keep in mind it's still beta, but I believe they will solve the issue pretty soon. I think that by now you could have found a workaround for this, but I'm going to post my solution based on your code, in case someone else runs into the same issue as we did. I hope this saves some time to someone else.Remember: This is a workaround, things are not intended to be done like this for other Lightning Components. They usually refresh the view based on events that the platform provides.
In my case, I had a record with address information and right next to it the address was displayed in the
lightning:map
, so if the address was updated, I wanted the map to update accordingly, without any extra steps for the user.1. For the map to update
MyMap.cmp
Line 3
Initialize the markers either here or in the controller, as mentioned by Jihad AZAMI HASSANI. This might not be an issue to you, but it can be for others because when the markers come from async data (a query, the Lightning Data Service, etc). You may get an exception because it tries to render and that variable doesn't have a value. Initializing with justdefault=""
will do.Lines 8 and 9
I added those variables there to use the lists in different methods in the controller.Line 13
You won't need to trigger that manually from the markup, I replicated that in the controller.Line 19
I needed to wrap thelightning:map
inside adiv
, I used that in the helper.MyMapController.js
Line 15
I moved the lists there to simplify the code that updates the displayed list, but you can move them back if you would like to.Line 67
That line does whatLine 13
did in MyMap.cmp.Lines 67, 76, 80 and 86
As you can see, I encapsulated the repeated code in MyMapHelper.js following the expected design pattern.MyMapHelper.js
updateMarkers
Basically, what I'm doing is overriding the content of the 'map-container'div
element for a brand new map, so I get a new component that gets initialized. As a side note, every time you change the data, the map's animation will play again. In your case, you should add the other properties that you were passing to the map in the markup, likecenter
,markersTitle
, etc. I think you wouldn't even need to have the originallightning:map
tag in the markup file.Note: As a different pattern, you could create a custom renderer, as
MyMapRenderer.js
, but it's a more complex approach. See here.2. When i have a list of 1 or less markers to show, the sidebar desapears.
I think that's a default behavior and I also think it can't be changed, like manually forcing the sidebar to show. I've been looking at the available information for in the Lightning Components Library and there aren't any properties that seem to have anything to do with that. They may include this in the future.
2. But if after i reset the list to 2 or more, the sidebar doesn't reappear.
This probably has to do with the re-rendering issue we addressed in Question 1, try again after using my code 😉
GOOD LUCK!