Ошибка типа: невозможно прочитать свойство 'FuId' из неопределенного - PullRequest
0 голосов
/ 29 октября 2018

Я работаю над небольшим приложением, в котором у нас есть группы, подгруппы и члены подгрупп. Группой в данном случае являются Области риска, которых в основном три. Даны идентификаторы 1,2 и 3 соответственно. В каждой из областей риска есть подгруппы, которые называются семейными единицами, и для каждой семейной единицы есть члены семьи. В зоне риска может быть около 127 семейных единиц, каждая со своими соответствующими членами.

У меня проблема с поиском членов семьи, сгруппированных по каждой семье. Я получаю результаты, но большинство из них не определены. В случае, когда в зоне риска 127 семейных единиц, я могу получить только около 24 семейных единиц с их членами, у которых более 100 неопределенных. Ниже мой контроллер

Мой контроллер

    .controller('familyRiskCtrl', ['$scope', 'familydataService', '$routeParams', function ($scope, familydataService, $routeParams) {
        $scope.familysR = [];

        $scope.currentPage = 1;
        $scope.itemsPerPage = 5;

        getDataRiskArea();

        // Gets family by risk area
        function getDataRiskArea() {
            familydataService.getFamilysByRiskArea($routeParams.id).then(function (result) {
                $scope.familyR = result;
                console.log(result);

                // variable to hold the families
                var familyUnit = [];                     

                // Get family by FSU Id (FuId)
                angular.forEach(result, function (value, key) {

                    familydataService.getFamilyByFuId(value.FuId).then(function (resulti) {

                        var familyResult = resulti;
                        var FuIds = resulti[key].FuId;

                        console.log(key);

                        // Push the array object to families
                        familyUnit.push({
                            Id: value.FuId,
                            FamilyUnitName: value.FamilyUnitName,
                            Families: familyResult
                        })
                    });
                });

                // console.log(families);
                console.log(familyUnit);
                $scope.FamilyUnit = familyUnit;
            });
        }

        $scope.sortBy = function (column) {
            $scope.sortColumn = column;
            $scope.reverse = !$scope.reverse;
        };
    }])

А ниже указана используемая услуга. Когда я консоль зарегистрировал результаты, я понял, что область риска получила все отличные идентификаторы семейных единиц, но при попытке получить членов под разными семейными единицами, он может извлечь только несколько ошибок броска для более чем 70% оставшихся данных, не тянул.

Обратите внимание, что я использовал значение angular.forEach () для отслеживания различных FuIds в массиве, когда они позже использовались для выборки членов семейной единицы.

Мой сервис

(function () {
'Use Strict'

angular
    .module('app')
    .factory('familydataService', ['$http', '$q', function ($http, $q) {
        var service = {};
        // Gets the Family by Risk Area ID
        service.getFamilysByRiskArea = function (id) {
            var deferred = $q.defer();
            $http.get('/Family/FamilyByRisk/' + id).then(function (result) {
                deferred.resolve(result.data);
            }, function () {
                deferred.reject();
            });
            return deferred.promise;
        };

        // Get family by FuID
        service.getFamilyByFuId = function (id) {
            var deferred = $q.defer();
            $http.get('/Family/FamilyByFuID/' + id).then(function (result) {
                deferred.resolve(result.data);
            }, function () {
                deferred.reject();
            });
            return deferred.promise;
        };

        return service;
    }]);
})();

А вот так выглядит мой console.log enter image description hereenter image description here

Исходя из вышеизложенного, существует 127 семейных единиц, извлеченных по идентификатору зоны риска, из которых 24 семейных единицы с их членами были получены с оставшимися неопределенными.

1 Ответ

0 голосов
/ 29 октября 2018

Вы пытаетесь проанализировать значение Id: value.FuId, во вложенном обещании, которое является асинхронной функцией.

  • foreach будет продолжен при следующем вызове, даже если familydataService.getFamilyByFuId(value.FuId) не завершил
  • метод возврата обещания имеет собственную область видимости блока

По этим двум причинам код будет нарушен из-за выхода за пределы вашей value переменной

Здесь вы создаете Http-вызов с 127 результатами, а затем вызов для каждого. Это всего 128 запросов на получение объекта. По отношению к максимальному размеру данных от всех возможных запросов всего $routeParams.id. Я предлагаю создать вызов API, возвращающий список DTO с необходимыми данными в сумме, позволяющий указывать временную стоимость для сервера за один вызов, используя индексы для таблиц или || и представление.

Хотя, если вы так думаете, попробуйте $q.all. Обман в том, что он разрешается в точном порядке , что дает вам преимущество индексации массива или по названию обещания, см. Справочник по API в конце.

Возвращает одно обещание, которое будет разрешено с помощью массива / хэша значений , каждое значение соответствует обещанию с тем же index / key в массиве / хэше обещаний. Если какое-либо из обещаний будет выполнено с отклонением, это полученное обещание будет отклонено с тем же значением отклонения.

$q.all({ a: funa('load'), b: funb('load') }).then(function (r) {
    console.log(r, r.a, r.b);
})
$q.all([ funa('load'),funb('load') ]).then(function (r) {
    console.log(r, r[0], r[1]);
})

попробуйте создать и вызвать функцию со вторым обещанием, анализируя необходимую вам переменную

function getDataRiskArea(id) {
    familydataService.getFamilysByRiskArea(id).then(function (result) {
        $scope.familysR = result;
        let unique = result;
        // Get family by FSU Id (FuId)
        $scope.getFamily(unique);
    }).finally(function () {
        console.log($scope.FamilyUnit);
    });
}
function getFamily(RiskRes) {
    let loop = RiskRes;
    var promises = [];
    for (var i = 0; i < loop.length; i++) {
        let callid = loop[i]['FuId'];
        var promise = familydataService.getFamilyByFuId(callid);
        promises.push(promise);
    }
    //here is by indexing
    $q.all(promises).then(data => {
        //Here Data is an array of results by its call 
        //So the loop order has the same results here 
        console.log('All promises have resolved', data);
        let res = [];
        for (var i = 0; i < loop.length; i++) {
            let obj = {
                Id: loop[i]['FuId'],
                FamilyUnitName: loop[i]['FamilyUnitName'],
                Families: data[i]
            };
            res.push(obj);
        }
        $scope.FamilyUnit = res;
    });
}

Вот несколько замечательных рефери, чтобы дать чек Цепочка нескольких обещаний , угловое обещание $ q.all и рабочий фрагмент.

'Use Strict';

function run($rootScope) {}
angular.module('app', [
]).controller('familyRiskCtrl', function ($scope, familydataService, $q) {
    $scope.familysR = [], $scope.tempUniqueIds = [];
    $scope.currentPage = 1;
    $scope.itemsPerPage = 5;
    // Gets family by risk area
    function getDataRiskArea(id) {
        familydataService.getFamilysByRiskArea(id).then(function (result) {
            $scope.familysR = result;
            let unique = result;
            // Get family by FSU Id (FuId)
            $scope.getFamily(unique);
        }).finally(function () {
            // this will be undefined to present you that this is async too 
            // and initiallized at the end  of getFamily
            console.log('FamilyUnit:',$scope.FamilyUnit);
        });
    }
    function getFamily(RiskRes) {
        let loop = RiskRes;
        var promises = [];
        for (var i = 0; i < loop.length; i++) {
            let callid = loop[i]['FuId'];
            var promise = familydataService.getFamilyByFuId(callid);
            promises.push(promise);
        }
        $q.all(promises).then(data => {
            //Here Data is an array of results by its call 
            //So the loop order has the same results order here 
            //That represents that data[i] is a result of loop[i]['FuId'] call
            //console.log('All promises have resolved', data);
            let res = [];
            for (var i = 0; i < loop.length; i++) {
                let obj = {
                    Id: loop[i]['FuId'],
                    FamilyUnitName: loop[i]['FamilyUnitName'],
                    Families: data[i]
                };
                res.push(obj);
            }
            $scope.FamilyUnit = res;
        });
    }

    $scope.getDataRiskArea = getDataRiskArea;
    $scope.getFamily = getFamily;

    $scope.sortBy = function (column) {
        $scope.sortColumn = column;
        $scope.reverse = !$scope.reverse;
    };
})
    .factory('familydataService', function ($http, $q, $timeout) {
        var service = {};
        var familyRiskAreaResult = [
            { FuId: 3, Area: 1, FamilyUnitName: 'Smiths' },
            { FuId: 1, Area: 1, FamilyUnitName: 'Jacksons' },
            { FuId: 4, Area: 1, FamilyUnitName: 'Monkey Jacksons' },
            { FuId: 2, Area: 1, FamilyUnitName: 'Stevens' },
            { FuId: 5, Area: 1, FamilyUnitName: 'Not unique also 3' }
        ];
        var familyUnit =
            [
                { Id: 1, FamilyUnitName: 'jks', Families: ['MJ', 'Janet', 'Latoia'] },
                { Id: 1, FamilyUnitName: 'jks', Families: ['Jacksons B1', 'Jacksons B2', 'Jacksons B3'] },
                { Id: 1, FamilyUnitName: 'jks', Families: ['Rebi', 'Dyana'] },
                { Id: 2, FamilyUnitName: 'Stvs', Families: ['Steven Seagal', 'Steven Tyler'] },
                { Id: 2, FamilyUnitName: 'Stvns', Families: ['King', 'Wonder'] },
                { Id: 3, FamilyUnitName: 'Smths', Families: ['MR', 'MRS'] }
            ];
        // Gets the Family by Risk Area ID
        service.getFamilysByRiskArea = function (id) {
            var deferred = $q.defer();
            //$timeout(function () {
                deferred.resolve(familyRiskAreaResult.filter(f => f.Area === id));
            //}, 1000);
            return deferred.promise;
        };

        // Get family by FuID
        service.getFamilyByFuId = function (id) {
            var deferred = $q.defer();
            //$timeout(function () {
            let res = familyUnit.filter(f => f.Id === id);
            let r = res.map(i => i.Families);
                deferred.resolve(r);
            //}, id * 1000);
            return deferred.promise;
        };
        return service;
    }).run(["$rootScope", run])    ;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<body ng-app="app">
    <div ng-controller="familyRiskCtrl">
        <div>
            <div style="display:inline-flex;"ng-repeat="b in [1,2,3]">
                <button ng-click="getDataRiskArea(b)">
                    <strong>Call Area {{b}}</strong>
                </button>
            </div>
        </div>
        <div>
            <h4>Area Loaded $refid</h4>
            <ul>
                <li ng-repeat="fam in familysR">
                    FuId: <strong>{{fam.FuId}} - {{fam.FamilyUnitName}}</strong>
                </li>
            </ul>
         </div>
        <div>
            <h4>Results</h4>
            <div ng-repeat="fu in FamilyUnit">
                <h5>{{fu.Id}} - {{fu.FamilyUnitName}}</h5>
                <div>
                    <span ng-if="fu.Families.length === 0">---No Families---</span>
                    <ul ng-if="fu.Families.length >0">
                        <li ng-repeat="f in fu.Families">{{f}}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</body>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...