Need help with $resource and (basic) Geocoding


#1

Hello,

In my app, I have to figure out where the user is, so that I can send lat and lng as query parameters with my $resource request.
This is my code:

angular.module('starter.services', ['ngResource'])
.factory('Pubs', function($resource) {
  // Get user position
  navigator.geolocation.getCurrentPosition(getPosition);
  function getPosition(position) {
    
    // Get pubs
    var httpRequest = $resource('http://my-domain.com/pubs', {}, {
      query: { 
        method: 'GET',
        isArray: true,
        params: {
          lat: position.coords.latitude,
          lng: position.coords.longitude
        } 
      }
    });

    pubs = httpRequest.query(function(response) {
      console.log(response);
    });
  }

  return {
    all: function() {
      return pubs;
    }
  };
});

It doesn’t work because by the time that HTML5 Geocoding has got back to me with the coordinates, the function has already returned. Moving all the code inside the callback does not work because I get an error saying ‘your services must return something’. I know it’s quite simple but I am stuck…
Any help would be greatly apreciated


#2

getPosition should not be called unless getCurrentPosition has received a value. Have you logged it to check the position data.


#3

getPosition is not called.
getPosition is the callback that gives me the position. GetCurrentPosition takes the reference of the function as an argument to inject the result into it. That bit works.


#4

@claudiocarmeli

You need to use a deferred promise in your factory.

Check out the code below. I have not tested it, but it should be close.

.factory('Pubs', function ($resource) {
	return {
		all: function () {
			var q = $q.defer();

			navigator.geolocation.getCurrentPosition(getPosition, errorCallback);

			function getPosition(position) {
				var httpRequest = $resource('http://my-domain.com/pubs', {}, {
					query: {
						method: 'GET',
						isArray: true,
						params: {
							lat: position.coords.latitude,
							lng: position.coords.longitude
						}
					}
				});

				httpRequest.query(function (response) {
					q.resolve(response);
				}, function (error) {
					q.reject(error);
				});
			}

			function errorCallback(error) {
				q.reject(error);
			}

			return q.promise;
		}
	};
})

#5

Thanks a bunch, mate! I didn’t know about these ‘deferred’ promises but it sounds exactly like something I would want in this case. Giving this a spin now!


#6

It works!!! Thanks a lot!
I get back a $promise with all the info inside. Need to go -> $$state -> value to fetch them

The small problem I am facing now is that I would like to show the stuff that I got back, on the screen without having to wait or refresh. I tried in the same way that I was doing before but nothing shows up…

My controller is

.controller('PubsCtrl', function($scope, Pubs) {
  $scope.$on('$ionicView.enter', function(e) {
    $scope.$apply(function() {

      // Does not work
      $scope.pubs = Pubs.all()

      // Does not work
      $scope.pubs = Pubs.all().$$state.value;
    });
  });
})

and my view is

<ion-view view-title="Dashboard">
  <ion-content class="padding">
    <h2>Welcome to Ionic</h2>
    <p>
      {{ pubs[3].id }}
    </p>
  </ion-content>
</ion-view>