Loading address data into google maps from database using Angularjs - javascript

I am using angularjs for my application.I am trying to load the address from user_address table in database and display it on map on load.
Here is the script i am using to load google maps
<script async defer src="https://maps.googleapis.com/maps/api/js?
key=myKey&callback=initMap">
</script>
Here is the html
<div id="map"></div>
<div id="repeatmap" data-ng-repeat="marker in markers | orderBy :
'title'">
<a id="country_container" href="#" ng-
click="openInfoWindow($event, marker)">
<label id="namesformap" >{{marker.title}}</label></a>
</div>
Here is the Controller.js
var DirectoryController = function($scope, $rootScope, $http,
$location, $route,DirectoryService,HomeService,$routeParams)
{
$scope.getAllCities = function()
{
DirectoryService.getAllCities().then(function(response){
$scope.cities = response.data;
console.log($scope.cities);
})
}
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(25,80),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.map = new google.maps.Map(document.getElementById('map'),
mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
var createMarker = function (info){
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.long),
title: info.city
});
marker.content = '<div class="infoWindowContent">' + info.desc +
'</div>';
google.maps.event.addListener(marker, 'click', function(){
infoWindow.setContent('<h2>' + marker.title + '</h2>' +
marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
for (var i = 0; i < $scope.cities.length; i++){
createMarker($scope.cities[i]);
}
$scope.openInfoWindow = function(e, selectedMarker){
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
}
In getAllCities function i am getting response from database that is all the names of cities.
As you can see in console i am able to get the response from database but i am not able to get $scope.cities value to for loop.It is saying Cannot read property 'length' of undefined.Can anyone tell how can i get value of $scope.cities into for loop so that in map i can display the cities returned from database.Now i am able to display map but with no cities and no markers.I dont know whether it will work or not or am i doing the wrong way?

This is most likely because you're trying to add the markers before the request to the database has finished resolving. This happens because the database/webservice request is most likely executed asynchronously.
Instead run the code for setting up the markers, when your promise from the database request have resolved. Like this:
var DirectoryController = function($scope, $rootScope, $http, $location, $route,DirectoryService, HomeService, $routeParams)
{
$scope.getAllCities = function()
{
DirectoryService.getAllCities().then(function(response){
$scope.cities = response.data;
console.log($scope.cities);
setupMapMarkers();
});
}
function setupMapMarkers(){
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(25,80),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
for (var i = 0; i < $scope.cities.length; i++){
createMarker($scope.cities[i]);
}
$scope.openInfoWindow = function(e, selectedMarker){
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
}
function createMarker(info){
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.long),
title: info.city
});
marker.content = '<div class="infoWindowContent">' + info.desc + '</div>';
google.maps.event.addListener(marker, 'click', function(){
infoWindow.setContent('<h2>' + marker.title + '</h2>' + marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
}

Related

How to assign values to javascript object through angularjs ng-click function

In the below code I am trying to set some values for google map's lat long, when I call the change function which is bound to ng-click directive, the page doesn't load, but without change() func everything loads pretty well. I might be missing some core concepts of angular that is because I have started working on it just 10 days before, kindly correct me here and if someone can suggest me another way to change my lat long with button click, I will be really thankful for that suggestion.
app.controller('MapCtrl', function ($scope){
// $scope.change=function(){
$scope.Latitude="23.200000";
$scope.Longitude="79.225487";
$scope.assignLat=function () {
var lati= $scope.Latitude;
return lati;
}
$scope.assignLong=function () {
var longi= $scope.Longitude;
return longi;
}
console.log($scope.assignLat());
console.log($scope.assignLong());
// }
var cities = [{
city : 'India',
desc : 'This is the best country in the world!',
lat : $scope.assignLat(),
long : $scope.assignLong()
}];
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(25,80),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
$scope.markers = [];
var infoWindow = new google.maps.InfoWindow();
var createMarker = function (info){
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.long),
title: info.city
});
marker.content = '<div class="infoWindowContent">' + info.desc + '</div>';
google.maps.event.addListener(marker, 'click', function(){
infoWindow.setContent('<h2>' + marker.title + '</h2>' + marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}
for (i = 0; i < cities.length; i++){
createMarker(cities[i]);
}
$scope.openInfoWindow = function(e, selectedMarker){
e.preventDefault();
google.maps.event.trigger(selectedMarker, 'click');
}
});

Google Places API - Angular Services

I'm trying to create a service in which I get a list of sites and the ability to share that data between controllers
angular.module('app')
.controller('googleMapCtrl', ['$scope', function($scope ){
var map;
$scope.placeNameArr = [];
console.log($scope.placeNameArr);
function initialise (position) {
$scope.$apply(function(){
var center = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map = new google.maps.Map(document.getElementById('map'),{
center: center,
zoom:12
});
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(),
new google.maps.LatLng());
var option = {
bounds: defaultBounds,
types: ['(cities)']
};
var input = document.getElementById('pac-input');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var autocomplete = new google.maps.places.Autocomplete(input, option) ;
var request = {
location: center,
radius: 8047,
types: [ 'restaurant' ]
// 'restaurant'
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
})
}
function callback(results, stattus) {
if(stattus == google.maps.places.PlacesServiceStatus.OK) {
for (var i=0; i < results.length; i++) {
var place = results[i]
createMarker(results[i]);
// console.log(results);
}
$scope.$apply(function () {
$scope.places = results;
});
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
photos = place.photos;
if (!photos) {
return;
}
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function(){
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' +
'Place ID: ' + place.place_id + '<br>' +
'<img src='+ place.photos[0].getUrl({'maxWidth': 175, 'maxHeight': 175}) +'>' + '<br>' + 'Rating:' + place.rating + '<img src='+ place.photos +'>' + '</div>');
infowindow.open(map,this);
})
console.log(place);
$scope.placeNameArr.push(place.name);
}
navigator.geolocation.getCurrentPosition(initialise);
// google.maps.event.addDomListener(window, 'load', initialize);
}])
I I'm not sure what approach i should take in this problem.
Ultimately i would like to share this results with Wikipedia API Controller
angular.module('app')
.controller('wikiCtrl', ['$scope','$http', function($scope, $http ){
var vm = $scope;
vm.searchTermArr = [];
vm.searchWiki = function(wikiFactory){
console.log(response);
}
vm.searchWiki = function(){
$http({
url: "http://en.wikipedia.org/w/api.php?action=opensearch&search=" + vm.searchTerm + '&format=json&callback=JSON_CALLBACK',
method: 'jsonp'
}).success(function(response){
console.log(response);
vm.searchTermArr.push(response[1]);
vm.searchTermArr.push(response[2]);
vm.searchTermArr.push(response[3]);
});
};
}]);
and get information based of long name of location ....
Thank you for all your suggestions.

How to match google maps marker ids with dynamically created ids on buttons

I want to have various buttons that open the corresponding info window on a google maps markers. I have looked at answers like THIS but they don't have dynamically created content. I am getting multiple locations from my db and showing them on a page. They have ids which I have added to the button. I have also added the corresponding ids to the markers (as seen HERE).
Now I just need to trigger the correct marker with the correct id. I think my problem is something to do with scope but I'm a bit lost. Using Laravel 5.
Code is all on a page called index.blade.php. User enters address in form which is geocoded to lat/lng then the nearest articles/stores are displayed on index.blade.php using the Articles Controller.
Code:
#extends('template')
#section('content')
#foreach ($articles as $article)
<i class="fa fa-plus-square showMoreDetails" onclick="myClick({{$article->id}});"></i>
#endforeach
#stop
#section('footer')
<script>
var barTitle = [
#foreach($articles as $article)
"{{$article->title}}" ,
#endforeach
];
var barDeal = [
#foreach($articles as $article)
"{{$article->deal}}" ,
#endforeach
];
var infoWindowContent = [];
var markers = [];
var i, marker;
function initialize() {
var map_canvas = document.getElementById('map_canvas');
var myLatlng = new google.maps.LatLng(parseFloat({{ $article->lat }}),parseFloat({{ $article->lng }}));
var map_options = {
center: myLatlng,
zoom: 15,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.BOTTOM_RIGHT
},
scaleControl: true,
panControl: true,
panControlOptions:{
position: google.maps.ControlPosition.BOTTOM_LEFT
},
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(map_canvas, map_options);
var locations = [
#foreach($articles as $article)
[{{$article->lat}}, {{$article->lng}}],
#endforeach
];
var barID = [
#foreach($articles as $article)
{{$article->id}},
#endforeach
];
for (i = 0; i < locations.length; i++) {
infoWindowContent[i] = getInfoWindowDetails(locations[i]);
var location = new google.maps.LatLng(locations[i][0], locations[i][1]);
var marker = new google.maps.Marker({
position: location,
map: map,
id: barID[i],
icon: 'images/happymarker.png'
});
var infowindow = new google.maps.InfoWindow()
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
// infowindow.setContent(barTitle[i]);
infowindow.setContent(infoWindowContent[i]);
infowindow.open(map, marker);
map.panTo(marker.getPosition());
map.setZoom(17);
}
})(marker, i));
markers.push(marker);
}
}
function getInfoWindowDetails(location){
var contentString = '<div id="infoWindowBox">' +
'<h3 id="firstHeading" class="infoWindowTitle">' + barTitle[i] + '</h3>'+
'<div id="bodyContent">'+
'<div>'+ barDeal[i] + '</div>'+
'</div>'+
'</div>';
return contentString;
}
google.maps.event.addDomListener(window, "load", initialize);
function myClick(id){
google.maps.event.trigger(markers[id], 'click');
}
</script>
#stop
My template.blade.php page loads maps like this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=MYKEY&signed_in=true&libraries=places"></script>
Articles Controller:
public function index(Request $request)
{
$lat = $request->get('lat');
$lng = $request->get('lng');
$distance = 1;
$categoryChoice = $request->get('categoryList');
$query = Article::distance($lat, $lng, $distance)
->whereHas('categories', function ($query) use ($categoryChoice) {
$query->whereIn('categories.id', $categoryChoice);
})->get();
$articles = $query;
if(count($articles) == 0)
{
return redirect()->action('HomeController#index');
}
return view('articles.index', compact('categories', 'articles', 'days'));
}
I worked it out. I had to use Laravel's 'search' function to find the index of the array of IDs of the articles. Then that integer matched the id of the markers.
#foreach ($articles as $article)
<!-- CREATE AN ARRAY OF IDS THEN GET THE INDEX/KEY OF THIS PARTICULAR ARTICLE ID -->
<?php $something = $articles->lists('id')
$artID = $article->id;
$key= $something->search($artID); ?>
<i class="fa fa-plus-square showMoreDetails" onclick="myClick(<?php echo $key; ?>);"></i>
#endforeach

how to use ng click and pass the id in google map pop window using angularjs?

i have two stores in database and am trying to get stores in google map marker is pointing that two stores.i have ng-click in that info window to pass id here ng-click is not working is there any idea to pass id through ng-click
.controller('MapCtrl', [
'$scope', '$http', '$location', '$window',
function ($scope, $http, $location, $window) {
$http.get('****').success(function (data, dealers, response) {
function initialize() {
var serverData = data;
$scope.locations = [];
for (var i = 0; i < serverData.length; i++) {
var modal = [
data[i].Store_Name, data[i].S_Location.Latitude, data[i].S_Location.Longitude, i, 'images/arrow.svg', data[i].S_Address];
$scope.locations.push(modal);
}
console.log($scope.locations);
//---------------------------------------------------------
//console i am getting like this
var locations = [
['nokia store', '12.971599', '77.594563', '1', 'images/arrow.svg.svg', '55a78953815356700bee698f'],
['samsung store', '12.9065534', '77.5774802', '2', 'images/arrow.svg.svg', '55a786d1815356700bee6982'], ];
//----------------------------------------------------------
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: new google.maps.LatLng(12.9667, 77.5667),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < $scope.locations.length; i++) {
//console.log($scope.locations[i][1]);
marker = new google.maps.Marker({
position: new google.maps.LatLng($scope.locations[i][1], $scope.locations[i][2]),
map: map,
icon: $scope.locations[i][4],
animation: google.maps.Animation.DROP,
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent('<div class="marker-box"><div class="marker-title">' + $scope.locations[i][0] + '</div><input type="button" value="Book Now" name="Book Now" ng-click="getid(' + $scope.locations[i][5] + ') "/></div>');
infowindow.open(map, marker);
}
})(marker, i));
}
$scope.map = map;
}
$scope.getid(id) {
console.log(id);
}
});
since 3 days i'm trying i can't able to solve.help me out
So in your code:
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent('<div class="marker-box"><div class="marker-title">' + $scope.locations[i][0] + '</div><input type="button" value="Book Now" name="Book Now" ng-click="getid(' + $scope.locations[i][5] + ') "/></div>');
infowindow.open(map, marker);
}
})(marker, i));
your call back function does not run until marker is clicked. By the time it's clicked, the scope probably does not know what "i" is. My guess is "i" becomes $scope.locations.length+1.
One things you can try:
put the above code in a secondary function, then call it from the main thread instead of running it directly from main thred. IE:
main code:{
//your code
for (i = 0; i < $scope.locations.length; i++){
function_name(parameter 1, i);
}
function function_name= above code;
Note the above is sudo code, please implement it and try it. Hope this solves it.

Different results in Google Places API and Google Maps

I'm using the Google Places JavaScript API for a desktop application. However, the search results returned by the API aren't the same as the ones I get in maps.google.com. For instance, if I search for "Antique Hostel", I get many results (almost all of them are kinda random) whereas on Google Maps I get the correct (single) result.
Is the quality of the search isn't the same in the API and the service?
Here is my code
function initialize() {
// map setup
var mapOptions = {
center: new google.maps.LatLng(52.519171, 13.406091199999992),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
$map = document.getElementById('mapCanvas'),
map = new google.maps.Map($map, mapOptions),
input = document.getElementById('searchInput'),
autocomplete = new google.maps.places.Autocomplete(input),
service = new google.maps.places.PlacesService(map),
$ajaxSearchInput = $(input),
markers = [];
autocomplete.bindTo('bounds', map);
$ajaxSearchInput.keydown(function(e) {
if (e.keyCode === 13) {
var request = {
query: $(this).val(),
radius: '500',
location: map.getCenter()
}
service.textSearch(request, searchCallBack);
}
});
searchCallBack = function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var bounds = new google.maps.LatLngBounds();
console.log(results);
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
for (var i = 0; i < results.length; i++) {
var place = results[i];
createMarker(results[i], bounds);
}
map.fitBounds(bounds);
}
}
createMarker = function(place, bounds) {
var marker = new google.maps.Marker({
map: map,
title: place.name,
position: place.geometry.location
});
// event listener to show the InfoWindow.
(function(marker, place) {
google.maps.event.addListener(marker, 'click', function() {
var content = '<h3>' + place.name + '</h3> ' + place.formatted_address + '<br>',
infowindow = new google.maps.InfoWindow({
content: ''
});
if (place.rating) {
content += '<p> <b>Rating</b>: ' + place.rating + '</p>';
}
if (place.types) {
content += '<p> <b>Tags</b>: ';
for (var j = 0, tag; tag = place.types[j]; j++) {
content += tag + ', '
}
content += '</p>';
}
infowindow.content = content;
infowindow.open(map, marker);
});
})(marker, place);
markers.push(marker);
bounds.extend(place.geometry.location);
}
}
google.maps.event.addDomListener(window, 'load', initialize);

Categories