How can I make several consecutive requests if the previous one did not give me results in angularjs

1
var appServices = angular.module('miClaroServices',[]);

appServices.factory('productoServicio', ['$http', '$q',
function($http, $q) {
    // interface
    var service = {
        ListProducto: [],
        getListProductos: getListProductos
    };
    return service;

    // implementation
    function getListProductos() {
        var def = $q.defer();

        $http.get('http://172.19.74.235:8909/ProductoServiciosResulFull/service/obtenerServicios/p')
            .success(function(data) {
                service.ListProducto = data;
                def.resolve(data);
            })
            .error(function() {
                def.reject('Failed to get ListProducto');
            });
        return def.promise;
    }
}]);

This is my controller

var appController = angular.module('miClaroController',[]);

    appController.controller('miClaroCtr', ['$scope', 'productoServicio',
    function($scope, productoServicio) {
        var text;
        var vm = $scope;
        vm.ListProducto = [];


        vm.getListProductos = function() {
            productoServicio.getListProductos()
                .then(function(ListProducto) {
                    vm.ListProducto = ListProducto;
                    console.log('Servicio returned to controller.' );
                    console.log(ListProducto);
                },
                function(data) {
                    vm.text = ("Error al consultar los clientes consumer");
                    console.log(text);
                });
        };

        vm.getListProductos();
    }
]);

What I need is that from the services, if $http.get does not bring anything, follow and consult another and so up to 4 JSON until in some there is data or not. Please could you help me since I'm new to Angular?

    
asked by jose.luis.lopez 14.06.2016 в 17:43
source

2 answers

1

This is something that has to do with the promises just chain them and you will have all the results you expect.

service.metodo1().then(function(resultado1) {
    return servicio.metodo2();
}).then(function(resultado2) {
    return servicio.metodo3();
}).then(function(resultado3) {
    return servicio.metodo4();
}).then(function(resultado4) {
    // fin de la cadena
}).catch(function() {
    // en caso que alguno falle se pasa al catch
});

In case you want to continue if the server sends you an empty answer even if it is not an error you can use the following

service.metodoX().then(function(resultado) {
    if (!resultado.data) {
        // también puede ser if (!resultado.data.lenght) en caso que sea un arreglo
        return servicio.siguienteMetodo();
    }

    // Si no devuelve nada el resultado de la siguente promesa será undefined
})
// ......
// idem a lo anterior

First of all I have to tell you that you should not structure your services as you show them. Use

var def = $q.defer();
//....
return def.promise;

It is usually a antipatron . If you are trying to cache the results there is a service for that.

Your service should look like this

var appServices = angular.module('miClaroServices',[]);

appServices.factory('productoServicio', ['$http', '$q',
function($http, $q) {
    var service = {
        getListProductos: getListProductos
    };
    return service;

    function getListProductos() {
        // Retorna directamente la promesa para manejarla en el controller
        return $http.get('http://172.19.74.235:8909/ProductoServiciosResulFull/service/obtenerServicios/p');
    }
}]);

And your controller

var appController = angular.module('miClaroController',[]);

appController.controller('miClaroCtr', ['$scope', 'productoServicio',
function($scope, productoServicio) {
    var text;
    var vm = $scope;
    vm.ListProducto = [];


    vm.getListProductos = function() {
        productoServicio.getListProductos()
            .then(function(ListProducto) {
                if (!ListProducto) {
                    vm.ListProducto = ListProducto;
                    return productoServicio.getOtraCosa();
                }
            })
            .then(function(otraCosa) {
                // Si la promesa anterior me retornó algo otraCosa es undefined y no entra en el if
                // En caso que sea una cadena vacia llamo al siguiente paso
                if (otraCosa === '') {
                    // o tambien if (!vm.ListProducto)
                    vm.ListProducto = otraCosa;
                    return productoServicio.getDeNuevo();
                }
            })
            .then(function(deNuevo) {
                if (deNuevo === '') {
                    vm.ListProducto = deNuevo;
                }
                // Este es el resultado final por lo que no se encadena más nada
                if (vm.ListProducto) {
                    // Si vm.ListProducto tiene algo es que algún paso me respondió
                }
            }, function(data) {
                // El error es el último ya que no necesitas mas de un manejo de errores en este caso
                vm.text = ("Error al consultar los clientes consumer");
                console.log(text);
            });
    };

    vm.getListProductos();
}

]);

Notice that in my first example I used

.then(function).then(function).catch(function)

while in the other use

.then(function).then(function, function)

The two are equivalent but it seems to me that the first one is much more readable than the second, so many times the second form is also considered a antipatron .

    
answered by 14.06.2016 в 18:55
0

in your service, it would be enough to do the following:

var appServices = angular.module('miClaroServices',[]);

appServices.factory('productoServicio', ['$http', '$q',
function($http, $q) {
    // interface
    var attempts = 0, service = {
        ListProducto: [],
        getListProductos: getListProductos
    };

    return service;

    // implementation
    function getListProductos() {
        var def = $q.defer();

        $http.get('http://172.19.74.235:8909/ProductoServiciosResulFull/service/obtenerServicios/p')
            .success(function(data) {
                if (!data || data.length == 0) {
                    attempts ++;

                    if (attempts <= 4) {
                        getListProductos();
                    } else {
                        def.reject('Failed to get ListProducto');
                        attempts = 0; // Reinicias en el servicio para proximas recuperaciones
                    }
                } else {
                    service.ListProducto = data;

                    def.resolve(data);
                }
            })
            .error(function() {
                def.reject('Failed to get ListProducto');
            });
        return def.promise;
    }
}]);

you add a variable attemps that is simply a counter of recovery attempts. Verify if the attempts you take are less than 4, then try to recover again, if not, you do reject indicating that your attempts failed.

    
answered by 14.08.2016 в 17:57