llamada http síncrona en AngularJS


Tengo el siguiente escenario, necesito datos de una url en particular. He escrito una función que toma el parámetro "url". Dentro de la función, tengo el $http.método get que hace una llamada a la url. Los datos se devolverán a la función de llamada

var getData = function (url) {
    var data = "";

    $http.get(url)
        .success( function(response, status, headers, config) {
             data = response;
        })
        .error(function(errResp) {
             console.log("error fetching url");
        });
    return data;
}

El problema es el siguiente, http http.get es asincrónico, antes de que se obtenga la respuesta, la función retorna. Por lo tanto, la función que llama obtiene los datos como cadena vacía. ¿Cómo fuerzo la función para no volver hasta los datos se han obtenido de la url?

Author: clearScreen, 2015-07-20

4 answers

Echa un vistazo a promesas para superar tales problemas, porque se utilizan en todo el lugar, en mundo angular.

Necesitas usar q q

var getData = function (url) {
    var data = "";
    var deferred = $q.defer();

    $http.get(url)
        .success( function(response, status, headers, config) {
             deferred.resolve(response);
        })
        .error(function(errResp) {
             deferred.reject({ message: "Really bad" });
        });
    return deferred.promise;
}

Aquí hay un buen artículo sobre promesas y q q

ACTUALIZACIÓN:

FYI, $http el servicio en sí devuelve una promesa, por lo que $q no se requiere necesariamente en este escenario(y por lo tanto un anti-patrón).

Pero no dejes que esta sea la razón para saltarte la lectura sobre $q y promesas.

Así que el código anterior es equivalente a lo siguiente:

var getData = function (url) {
    var data = "";
    return $http.get(url);
}
 17
Author: nalinc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-18 08:43:31

También puedes usar el método q q.all() para resolver este problema

var requestPromise = [];

var getData = function (url) {
    var data = "";

    var httpPromise = $http.get(url)
        .success( function(response, status, headers, config) {
             data = response;
        })
        .error(function(errResp) {
             console.log("error fetching url");
        });

    requestPromise.push(httpPromise);
}

En la función que llama

$q.all(requestPromise).then(function(data) {

    //this is entered only after http.get is successful
});

Asegúrese de inyectar $q como dependencia. Espero que ayude

 9
Author: akashrajkn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-21 01:48:55

Una forma típica de hacer lo que quieres es así:

var getData = function(url, callback) {
    $http.get(url).success(function(response) {
        callback && callback(response);
    });
};

Usado como:

getData('/endpoint', function(data) {
    console.log(data);
});
 5
Author: Marty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-20 05:42:27

Tu función parece redundante. Simplemente use $http.get(url), ya que realmente no está haciendo nada más antes de usarlo de todos modos.

var url = 'foo/bar';

$http
    .get(url)
    .success( function(response, status, headers, config) {
        $scope.data = response;
    })
    .error(function(errResp) {
        console.log("error fetching url");
    });

O si necesita acceder a la promesa más tarde, simplemente asígnela a variable;

var promise = $http.get(url);

// some other code..

promise.then(function(data){
   //.. do something with data
});
 5
Author: Matt Herbstritt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-20 06:00:06