1

I am just calling api which returns josn encoded data and trying to print object property but shows undefined but when I print that object , the object has that property and value.

my code

function sendData(postData, url){
        var response = apiCall(postData,url);
        console.log(response.email)
        console.log(response.count);
    }


    function apiCall(postData, postUrl){
        var response = {};
        $http({
            method  : 'POST',
            url     : postUrl,
            data    : postData, 
            headers : {'Content-Type': 'application/json'}
         }).success(function(data) {  
                console.log(data)
                for (var attr in data) {
                    if (data.hasOwnProperty(attr)) response[attr] = data[attr];
                }  
           });

         return response;   
    }

php based api

<?php 
    $_POST = json_decode(file_get_contents('php://input'), true);
    $response = array();

    $response['email'] = $_POST['oauth']['email'];
    $response['type'] = $_POST['oauth']['type'];
    echo json_encode($response);
?> 

response data in console

Object {email: "sameerdighe14@gmail.com", type: "google"}

SaMeEr
  • 361
  • 2
  • 7
  • 22

2 Answers2

1

You need to use promises to make it work. Your success function is called async once the HTTP-Request has finished with success. In that way return response; is executed before the request has been finished -> so it is still an empty object {}. Use AngularJS promises to make it work. This is a simple working fiddle example.

function sendData(postData, url){

    var filteredData = {};

    apiCall(postData,url).then(function (response) {

        for (var attr in response.data) {
            if (response.data.hasOwnProperty(attr)) {
                filteredData[attr] = response.data[attr];
            }
        }

        console.log(filteredData.email);
        console.log(filteredData.count);
    });
}


function apiCall(postData, postUrl){
    return $http({
        method  : 'POST',
        url     : postUrl,
        data    : postData,
        headers : {'Content-Type': 'application/json'}
    });
}
lin
  • 17,956
  • 4
  • 59
  • 83
-1

The code is not running in the order which you expect. $http takes time to run, and therefore apiCall is returning response before it's been modified.

To fix this, you need to use a promise to ensure that your code runs only when you have all of the data which you need.

Additionally, the data returned from $http has a property data which contains the result from the call.

function sendData(postData, url) {
  // subscribe to promise, and add your code in the then block
  apiCall(postData,url)
    .then(function(response) {
      console.log(response.email);
      console.log(response.count);
    });
}

function apiCall(postData, postUrl) {
  // return the promise
  return $http({
    method  : 'POST',
    url     : postUrl,
    data    : postData, 
    headers : {'Content-Type': 'application/json'}
  }).success(function(response) { 
    var result = {};
    for (var attr in response.data) {
      if (response.data.hasOwnProperty(attr)) {
        result[attr] = response.data[attr];
      }
    }  
    return result;   
  });
}

Note that the data property from a $http request is guaranteed to be a plain object without extra properties on its prototype, so you don't really need the hasOwnProperty check. apiCall can be simplified:

function apiCall(postData, postUrl) {
  // return the promise
  return $http({
    method  : 'POST',
    url     : postUrl,
    data    : postData, 
    headers : {'Content-Type': 'application/json'}
  }).success(function(response) { 
    return response.data;
  });
}
clinton3141
  • 4,751
  • 3
  • 33
  • 46
  • This will not work. `.then(function(response)` holds the raw callback data of `$http` and not the data returned by the success part. – lin Mar 02 '17 at 08:04
  • `success` returns a promise. Therefore any modification are kept. Source: https://github.com/angular/angular.js/blob/3a3db690a16e888aa7371e3b02e2954b9ec2d558/src/ng/http.js#L910 – clinton3141 Mar 02 '17 at 08:15
  • True, but this promise is for handling the success promise itself. Please check https://github.com/angular/angular.js/blob/3a3db690a16e888aa7371e3b02e2954b9ec2d558/src/ng/http.js#L415 & http://jsfiddle.net/5uancso0/ – lin Mar 02 '17 at 08:26
  • Please bring some feedback, this discussion is also interesting to me – lin Mar 02 '17 at 15:12