0

I want a service that grabs info from an API but only after clicking an HTML element.

"freegeoip.net/json/" + ip_address

The problem is, my service and URL above is being called before the click occurs.

app.service("ips", function ($http, $q)
{
    // Grab json
    var deferred = $q.defer();
    $http.get("http://www.freegeoip.net/json/" + ip_address).then(function (data)
    {
        deferred.resolve(data);
    });

    this.getItems = function ()
    {
        console.log(deferred.promise);
        return deferred.promise;
    }
})

Can someone show me I can define this variable ip_address later in a click?

///Inside the controller

promise.then(function (data)
{
    $scope.items = data.data.items;
});
$scope.defineIP= function(item)
{
   ip_address = "212.38.168.60"
   return ip_address;
}

The problem here is that I have no clue how to take this value i defined for ip_address and inject it into the service.

Ian Steffy
  • 1,234
  • 3
  • 18
  • 45
  • 1
    are you calling getItems Method in controller on click of some element ? post the code related to it ! – user1608841 Jul 28 '17 at 11:10
  • 1
    the getItems method is being called immediately when the controller is initialized. If you have a smarter way of doing this, i'm happy to hear it. – Ian Steffy Jul 28 '17 at 11:16

2 Answers2

2

Your Code should go like this.

app.service("ips", function ($http) {
    this.getItems = function (ip_address) {
       return  $http.get("freegeoip.net/json/" + ip_address)
    }
});

and in controller :

$scope.defineIP= function(){
   var ip_address = "212.38.168.60"
   ips.getItems(ip_address).then(function(response){
     console.log(response);
   }) 
}

Dont forget to add "ips" as DI in controller.

As you want to grab info on click of HTML element then you should call like below:

 <button ngClick="defineIP()">Click Here</button>

You dont need to inject $q in service as $http returns you the Promise Object so that you can use .then() method directly in controller

georgeawg
  • 48,608
  • 13
  • 72
  • 95
user1608841
  • 2,455
  • 1
  • 27
  • 40
  • This is also 100% correct and works. I am torn as to which Answer I should give the Green Check to. Who's answer is more efficient? – Ian Steffy Jul 28 '17 at 11:51
  • 2
    your choice ... :) however never use $q in $http (may be sometimes in some cases you may need to use $q); it actually returns promise – user1608841 Jul 28 '17 at 12:04
0

The $http request will be called once u inject the service. So you should be called like this.

app.service("ips", function ($http, $q)
{
    // Grab json    

    this.getItems = function (ip_address)
    {
        var deferred = $q.defer();
        $http.get("freegeoip.net/json/" + ip_address).then(function (data)
        {
          deferred.resolve(data);
        });
        return deferred.promise;
    }
})

In controller:

var promise = ipsService.getItems(ip_address);
Indhu
  • 371
  • 1
  • 5
  • 18
  • And then in the controller, which has the service ips, do I call this.getItems(someIPstring)? – Ian Steffy Jul 28 '17 at 11:17
  • Your answer as well Rahul's are correct but I can only give one green check. Who's is more efficient? – Ian Steffy Jul 28 '17 at 11:52
  • 1
    This is a $q.defer anti-pattern. The promise hangs if the $http request is rejected. See [Is this a “Deferred Antipattern”?](https://stackoverflow.com/questions/30750207/is-this-a-deferred-antipattern). – georgeawg Jul 28 '17 at 13:32