0

Im trying to create a get function that will have a dynamic URL for variables needed from an api. I am assigning the $scope variable to the returned data however I cannot access it. I console log the variable and it returns undefined. Below is my code.

app.controller('Controller', function ($scope, $http) {

  var getRequest = function (url) {
    $http({
            method: 'GET',
            dataType: "json",
            url: url
        }).then(function (response) {
            console.log(response);
            return response;
        }),
        function error(err) {
            console.log("This ain't working..." + err);
        }
}

$scope.firstURL = getRequest('https://url1');
$scope.secondURL = getRequest('https://url2');
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
William.Doyle
  • 79
  • 1
  • 10
  • Add this line $scope.firstURL = response; inside your .then call back function. – Thangadurai Apr 25 '17 at 12:31
  • @Thangadurai then id need to have multiple get requests for each variable. I would need a second get request with $scope.secondURL = response. Im trying to just reuse one get request for multiple variables. – William.Doyle Apr 25 '17 at 12:36
  • @William.Doyle Then move this to a service/factory layer and use it as needed. I have an example below, app.factory('myService', function($http) { return { async: function() { return $http.get('test.json'); //1. this returns promise } }; }); – CrazyMac Apr 25 '17 at 12:39
  • 1
    You're returning the entire $http response; you probably want `response.data`. – Daniel Beck Apr 25 '17 at 12:43
  • Possible duplicate of [How to use $http promise response outside success handler](http://stackoverflow.com/questions/35275451/how-to-use-http-promise-response-outside-success-handler) – georgeawg Apr 25 '17 at 13:04

2 Answers2

4

getRequest has no return statement, this is why it returns undefined. Also, then callbacks are invoked asynchronously. If you would like to assign server responses to $scope vars, you should do this inside of then callback:

var getRequest = function (url) {
    return $http({
            method: 'GET',
            dataType: "json",
            url: url
        });
}

getRequest('https://url1').then(function (response) {
    $scope.firstURL = response;
}));
getRequest('https://url2').then(function (response) {
    $scope.secondUrl = response;
}));
Alina Loi
  • 184
  • 6
  • Thank you Kind stranger, that is exactly what I was getting wrong. asynchronous promises stuff is kind of hard to understand but thank you for the help – William.Doyle Apr 25 '17 at 12:59
  • Could this be used for a POST and PUT request as well? – William.Doyle Apr 25 '17 at 13:27
  • Yes, sure; this should be valid for all promises. Let me know if you have any issue. – Alina Loi Apr 25 '17 at 13:28
  • For the PUT and POST request how would I know that the request has been successful? Currently im getting an error "Cannot read property 'then" when using the post method postRequest('url',data).then(function (response) { console.log(response); }); – William.Doyle Apr 25 '17 at 14:51
  • @William.Doyle Make sure you return `$http(...)` in `postRequest` function, not just execute it. In case it does not help, please show me the `postRequest`. If request succeeds, a success callback (1st one in `then(...)`) will be invoked. Otherwise an error callback (2nd one) will be invoked. – Alina Loi Apr 25 '17 at 14:57
  • This is the post request: var postRequest = function (url, data) { $http({ method: 'POST', data:data, url: url }); } – William.Doyle Apr 25 '17 at 15:02
  • @William.Doyle , you should **return** $http(...) in postRequest: `var postRequest = function (url, data) { return $http({ method: 'POST', data:data, url: url }); `. Otherwise it is the same to `return undefined;` in the end of function. – Alina Loi Apr 25 '17 at 15:07
0

As you can see from this Js Bin you can achieve what you need with the following.

angular.module('myApp', []);

angular.module('myApp')
       .controller('MyController', MyController);

MyController.$inject = ['$http', '$log'];

function MyController($http, $log){

  var vm = this;

  vm.nick1 = 'AndreaM16';
  vm.nick2 = 'Aspha9';
  vm.gitUrl = 'https://api.github.com/users';

  vm.data1 = '';
  vm.data2 = '';

  getSomeData(vm.gitUrl + '/' + vm.nick1).then(function(res){
    vm.data1 = res.data;
    $log.log(vm.data1);
  });

  getSomeData(vm.gitUrl + '/' + vm.nick2).then(function(res){
    vm.data1 = res.data;
    $log.log(vm.data2);
  });

  function getSomeData(url){
    return $http({
                    method: 'GET',
                    dataType: "json",
                    url: url
    });
  }


}

As @Alina Loi Said, the asynchronous nature of the call forces you to get the response using .then().

AndreaM16
  • 3,917
  • 4
  • 35
  • 74