Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
20
rated 0 times [  21] [ 1]  / answers: 1 / hits: 26789  / 12 Years ago, fri, january 25, 2013, 12:00:00

I'm using AngularUI's uiMap directives to instantiate a google map. The uiMap directive works great with hard-coded data ({mapOptions} and [myMarkers]); however I run into trouble when I retrieve this data via $http.get() (the directive fires before the AJAX call has finished).



Initially I was executing the GET in my GoogleMaps controller, but when I realised things were happening out of sequence, I moved the GET into the uiMap directive. I've got 2 problems with this:




  1. I think this is not the correct way to do this.

  2. The GET also retrieves the data for [myMarkers]
    • The function/directive that creates the markers is ubiquitous in that it is responsible for creating all overlays




So my question is, is there somewhere else in the application where I can retrieve the data (and apply it to scope) before the directive runs?



I read up on $q, and that kind of sounds like what I want, but I'm not sure if I can do it within my controller rather than in the directive (also not sure how $q.defer.resolve() is any different than $http.success()).



EDIT Most of the code I'm using is copy/paste from AngularUI's doc, but here's a plunk: http://plnkr.co/edit/t2Nq57



Solution



Based on Andy's answer, I used a combination of uiMap and uiIf:



<!-- index.html -->
<div
id=map_container
ng-controller=GoogleMaps>

<div ui-if=mapReady>

<div
ng-repeat=marker in markers
ui-map-marker=markers[$index]
ui-event={'map-click':'openMarkerInfo(marker)'}
></div>

<div
ui-map-info-window=myInfoWindow
ng-include='infobox.html'
></div>

<div
id=map_canvas
ui-map=myMap
ui-options=mapOptions
></div>

</div>

</div>


Caveat 1 uiIf cannot be in the same element that specifies the controller furnishing its condition (uiIf has higher priority than ngController, so its controller won't get set before uiIf executes).



Caveat 2 Be sure to use the most recent version of uiIf (the version supplied in the most recent tag, v0.3.2, is out of date). The old one has bug causing a TypeError under certain circumstances.



Caveat 3 jQuery MUST be included before AngularJS (in index.html); else you will receive a TypeError stating that Object [object Object] has no method 'trigger' (or Object [object HTMLDivElement] has no method 'trigger' on Windows). Chrome will allow you to step into the trigger function because Chrome knows about it, but Angular does not (and Angular is throwing the error).



function GoogleMaps( $scope , $http )
{

var mapDefaults = {
center: new google.maps.LatLng(25,-90),//centres on Gulf of Mexico
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};

$scope.mapOptions = {};
$scope.mapReady = false;
$scope.markers = [];

$http.get('map.json').then(function mapData(response) {

var map_data = response.data,
user_defaults = map_data.user.defaults; //{center: [lat,lng], zoom: 15}

$scope.mapOptions = {
center: (typeof user_defaults.center !== 'undefined') ?
new google.maps.LatLng(user_defaults.center[0],user_defaults.center[1])
: mapDefaults.center,
zoom: (typeof user_defaults.zoom !== 'undefined') ?
parseInt(user_defaults.zoom,10)
: mapDefaults.zoom,
mapTypeId: mapDefaults.mapTypeId
};

//working on code to populate markers object

$scope.mapReady = true;

});

// straight from sample on http://angular-ui.github.com/#directives-map
$scope.addMarker = function($event) { … };
$scope.openMarkerInfo = function(marker) { … };
$scope.setMarkerPosition = function(marker, lat, lng) { … };

}//GoogleMaps{}


Drawback uiMap does not currently support rendering makers on domready. I'm looking into an alternative version of uiMapMarker suggested in this GitHub issue / comment.

Solution to this issue: https://stackoverflow.com/a/14617167/758177

Working example: http://plnkr.co/edit/0CMdW3?p=preview


More From » html

 Answers
20

You could just delay execution of ui-map until your data is loaded.



HTML:



<div ui-if=loadingIsDone>
<div ui-map=myMap ui-options=myOpts></div>
</div>


JS:



$http.get('/mapdata').then(function(response) {
$scope.myOpts = response.data;
$scope.loadingIsDone = true;
});

[#80621] Thursday, January 24, 2013, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
keyonnaelled

Total Points: 35
Total Questions: 113
Total Answers: 99

Location: South Korea
Member since Fri, Sep 11, 2020
4 Years ago
;