4

Currently I'd like to get data from an API, sending some search parameters using an AngularJS service. In my ng-model I have a variable called search, and I would like to use that variable as a parameter to the API URL.

My first (unsuccessful) approach was to use the $scope.search variable directly inside the service:

$http.get('http://www.omdbapi.com/?s='+ $scope.search +'&type=series&r=json').then(function(data){
     deferred.resolve(data);
});

I've read that passing the $scope to the service is not possible (and shouldn't be done anyway), so how can I use the scope variable as a parameter in the service, also, is there a cleaner way to set the paramaters other than adding the string myUrl + search?

full code:

 myApp.service('showsService', function($http, $q){
    var deferred = $q.defer(); //promise to say 'im going to do this later'
    $http.get('http://www.omdbapi.com/?s=sherlock&type=series&r=json').then(function(data){
        deferred.resolve(data);
    });
    this.getShows = function(){
        return deferred.promise;
    }
    });

    myApp.controller("showsController", function($scope, showsService){
    $scope.$watch('search', function() {
      fetch();
    });

    function fetch(){
        var promise = showsService.getShows();
        promise.then(function(data){
        $scope.showsResult = data.data.Search; //using the name than comes back from the API
    });
    }
    });
3
  • the answer to your question is in the other question you referenced. Did you try implementing the solution provided there before asking essentially the same question again? Commented Oct 13, 2016 at 0:29
  • in the given solution they don't use the http.get function which i'm using, neither do they use a service -as far as I can see- since they implement a factory? Commented Oct 13, 2016 at 0:37
  • 2
    the concept is still the same, but your code is all wrong here anyway. You are trying to call the $http.get when the service is initialized (app startup), and since services are singletons, it's only ever going to make the call once. also, $http returns a promise, so you shouldn't wrap that promise inside another promise (don't use $q here). pass your parameter to your getShows(searchTerm), call your $http.get inside that function, and return that, to chain .then() from. Commented Oct 13, 2016 at 0:44

2 Answers 2

2

Simply pass search as an argument to the service function:

myApp.service('showsService', function($http){
    this.getShows = function(search){
        var url = 'http://www.omdbapi.com/s='+search+'&type=series&r=json';
        var promise = $http.get(url);
        return promise;
    };
});

Then in the controller:

myApp.controller("showsController", function($scope, showsService){
   $scope.$watch('search', function(value) {
      fetch(value);
   });

   function fetch(search){
       var promise = showsService.getShows(search);
       promise.then(function(response){
           $scope.showsResult = response.data.Search;
       });
    };
});

There is no need to manufacture a promise with $q.defer as the $http service already returns a promise.


Update

The $http service is able to serialize parameters:

myApp.service('showsService', function($http){
    this.getShows = function(search){
        //var url = 'http://www.omdbapi.com/s='+search+'&type=series&r=json';
        var url = 'http://www.omdbapi.com/'
        var config = { 
            params: { 
                s: search,
                type: 'series',
                r: 'json'
            }
        };
        var promise = $http.get(url, config);
        return promise;
    };
});
Sign up to request clarification or add additional context in comments.

3 Comments

Please use the $http params config object ~ $http.get('http://www.omdbapi.com', { params: { s: search, type: 'series', r: 'json' } }). Concatenating strings into URL query parameters is not safe
great, thanks! i got the idea of using the $q.defer from a video tutorial on youtube, but now i understand better the use of $http, cheers!. I will also try to use the params config object as suggested by @Phil
These Angular tutorials remind me of all the terrible PHP tutorials and all the damage they did
0

You can directly pass the search data to service

var getShows = showsService.getShows($scope.search);
getShows.then(function(resposne){
    console.log(resposne.data);
})

Service code

myApp.service('showsService',['$http',function commonSrv($http) {
this.getShows=function(search)
      {
        var promise = $http({
          method: 'post',
          url: 'http://www.omdbapi.com/',
          data:{"s":search, 'type':'series'},
          contentType:'application/json; charset=UTF-8',
        });
        return promise;
      };
}]);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.