Как передать данные из одной асинхронной в другую асинхронную функцию в AngularJS - PullRequest
0 голосов
/ 09 мая 2019

Как передать значение глобальной переменной из одной функции в другую функцию в угловом формате?

У меня есть 2 глобальные переменные:

$scope.genewtId = null;
$scope.data1 = null;

У меня есть 2 угловые функции, которые выглядят следующим образом:

$scope.getID = function() {
    Service1.getId("abc").then(function(response){
        $scope.genewtId = response.data[0].Id;
        console.log($scope.genewtId);

    }, function(error){
        console.log(error.statusText);
    });
};

$scope.getDetails = function() {
    Service2.getDetails($scope.genewtId).then(function(response){
        // here response is having an error
        $scope.data1 = response.data;
        console.log($scope.data1.toString());
    }, function(error){
        console.log(error.statusText);
    });
};

Когда я передаю значение $scope.genewtId из одной функции в другую, я получаю сообщение об ошибке

: «Не удалось преобразовать значение типа» java.lang.String 'к необходимому типу' java.lang.Integer '; вложенным исключением является java.lang.NumberFormatException: для входной строки: "null" "

Однако console.log($scope.genewtId); возвращает значение 787651, что означает, что оно не равно нулю.

Пожалуйста, предложите, если это может быть реализовано с помощью $rootScope.$broadcast

Ответы [ 3 ]

1 голос
/ 09 мая 2019

Обещания от двух служб должны быть прикованы

Измените первую функцию для возврата обещания:

$scope.getID = function() {
    return Service1.getId("abc").then(function(response){
        $scope.genewtId = response.data[0].Id;
        console.log($scope.genewtId);
        return response.data[0].Id;
    }, function(error){
        console.log(error.statusText);
        throw error;
    });
};

Измените вторую функцию, чтобы она возвращала обещание и принимала аргумент:

$scope.getDetails = function(id) {
    var genewtID = id || $scope.genewtId;
    return Service2.getDetails(genewtId).then(function(response){
        $scope.data1 = response.data;
        console.log($scope.data1.toString());
        return response.data;
    }, function(error){
        console.log(error.statusText);
        throw error;
    });
};

Тогда цепь два обещания:

var promise = $scope.getId();

var promise2 = promise.then(function(id) {
                   return $scope.getDetails(id);
               });

var promise2.then(function(data) {
     console.log(data);
}).catch(function(error) {
     console.log(error);
});

Используя метод .then обещания getId, код ожидает поступления значения id с сервера, прежде чем отправлять запрос на getDetails.

Поскольку вызов метода обещания .then возвращает новое производное обещание, можно легко создать цепочку обещаний. Можно создать цепочки любой длины, и, поскольку обещание может быть разрешено с помощью другого обещания (что приведет к дальнейшему отложению его разрешения), возможно приостановить / отложить разрешение обещаний в любой точке цепочки.

Для получения дополнительной информации см.

1 голос
/ 09 мая 2019

Единственная причина, по которой я могу придумать, - это asynchronous вызов promises. Вот что происходит:

Каким-то образом вы звоните Service2.getDetails($scope.genewtId) до того, как значение $scope.genewtId будет установлено после завершения обещания Service1.getId("abc").then, и поэтому значение остается null

Попробуйте:

$scope.getID = function(isCalledAfterDetails) {
    Service1.getId("abc").then(function(response){
        $scope.genewtId = response.data[0].Id;
        console.log($scope.genewtId);
        if(isCalledAfterDetails && $scope.genewtId !== null){
            $scope.getDetails();
        }

    }, function(error){
        console.log(error.statusText);
    });
};

$scope.getDetails = function() {
    if($scope.genewtId === null){
        $scope.getID(true);
    }else{
        Service2.getDetails($scope.genewtId).then(function(response){
            // here response is having an error
            $scope.data1 = response.data;
            console.log($scope.data1.toString());
        }, function(error){
            console.log(error.statusText);
        });
    }

};

Даже если этот подход работает, я настоятельно рекомендую вам реализовать вызовы функций лучше, поскольку $scope.getDetails() зависит от $scope.getID() для установки значения $scope.genewtId.

Если вы хотите получить предложение о том, как его реализовать, обновите вопрос, указав вариант использования и еще немного кода

Обновление

$scope.getID = function() {
    Service1.getId("abc").then(function(response){
        $scope.genewtId = response.data[0].Id;
        $scope.getDetails();
    }, function(error){
        console.log(error);
    });
};

$scope.getDetails = function() {
        Service2.getDetails($scope.genewtId).then(function(response){
            // here response is having an error
            $scope.data1 = response.data;
            console.log($scope.data1.toString());
        }, function(error){
            console.log(error.statusText);
        });        
};

Использование услуги

В service.js

getDetails = function(id){
    var deferred = $q.derfer();
    $http.get('/user/'+id).then(function(response){
        var newId = response.data[0].Id;
        $http.get('/user/details'+newId).then(function(details){
            deferred.resolve(details)
        })
    })      
    return deferred.promise;
}

controller.js

$scope.getDetails = function() {
        MySvc.getDetails("abc").then(function(response){
            console.log(response) // your details here
        }, function(error){
            console.log(error.statusText);
        });        
};
0 голосов
/ 09 мая 2019

Похоже, исключение исходит со стороны сервера.

Не удалось преобразовать значение типа 'java.lang.String' в требуемый тип 'java.lang.Integer';вложенное исключение: java.lang.NumberFormatException: для входной строки: "null"

Это печатается на консоли из-за console.log(error.statusText);

Вам необходимо проверить логику, когдазначение используется в API.

...