Невозможно прочитать свойство 'data' из undefined даже не запущенного запроса $ http.get - PullRequest
0 голосов
/ 30 декабря 2018

У меня есть веб-приложение, созданное предыдущей компанией, написанное на Angular.JS.
Приложение предоставляет запрос на сервер (написанный на Node.JS + Express), чтобы собрать некоторые данные, необходимые для заполнения таблицы.
В частности, это запрос, который приложение отправляет каждый раз, когда пользователь входит на страницу, содержащую таблицу (переменная config содержит маркер доступа).

define(['app'], function (app) {

    app.factory('AdvService', AdvService);

    AdvService.$inject = ['BasicService'];
    function AdvService(BasicService) {

      var service = angular.extend(BasicService, {});
      var $http = service.$http;
      var API = service.API
      var handleSuccess = service.handleSuccess;
      var handleError = service.handleError;
      var config = {
        params: {
            'token': JSON.parse(window.sessionStorage.getItem('session')).token
        }
      };

      service.searchByCriteria = function (criteria) {
        debugger;
        config.params.pageNumber = criteria.pageNumber;
        config.params.pageSize = criteria.pageSize;
        return $http.get(API + '/api/v2/admin/ads/getAdsByCriteria', config).then(handleSuccess, handleError);  
      };

      service.createAd = function (ad) {
        debugger;
        return $http.post(API + '/api/v2/admin/ads/insertNewAd', ad, config).then(handleSuccess, handleError);
      };

      return service;      
    }

});

handleSuccess и handleError определены так

define(['app'], function (app) {

    app.factory('BasicService', BasicService);

    BasicService.$inject = ['CONF', '$http', '$window', '$q'];
    function BasicService(CONF, $http, $window, $q) {

        $http.defaults.headers.common['x-access-token'] = JSON.parse($window.sessionStorage.getItem('session')).token;

        return {
            $http: $http,
            API: CONF.API_URL,

            handleSuccess: function (res) {
                debugger;
                var deferred = $q.defer();
                res.data.success ? deferred.resolve(res.data) : deferred.reject(res.data.message);
                return res.data;
            },

            handleError: function (error) {
                debugger;
                return {
                    success: false,
                    message: error
                };
            }
        }

    }
})

, и это единственная точка приложения, которая вызывает эту службу

    ($scope.search = function () {
        debugger;
        AdvService.searchByCriteria($scope.searchCriteria).then(function (res) {
            debugger;
            $scope.searchRes = res.data.docs;
            //$scope.gridOptions.totalItems = res.data.total;
        }, function (err) {
            console.log(err);
        });
    })();

.запрос CORS (внешний порт находится на порте 8010, а другой - на другом), я вижу из системы сетевого мониторинга Chrome, что часть $ http.get выполняется дважды, но вот моя проблема: даже до начала обработкипри выполнении первого вызова, внешний интерфейс генерирует ошибку

angular.js:14961 TypeError: Cannot read property 'data' of undefined
    at Object.<anonymous> (ui-grid.js:3291)
    at Object.invoke (angular.js:5117)
    at $controllerInit (angular.js:11139)
    at nodeLinkFn (angular.js:10002)
    at angular.js:10410
    at processQueue (angular.js:17330)
    at angular.js:17378
    at Scope.$digest (angular.js:18515)
    at Scope.scopePrototype.$digest (hint.js:1495)
    at Scope.$apply (angular.js:18903)

, и даже если запрос возвращает данные после сбоя, Angular не может правильно отрендерить все.
Единственное, что я попробовал, - это использовать механизм Await / Async, чтобы попытаться подождать и посмотреть, что могло произойти, но это всегда разрешается в приведенной выше ошибке.
Кто-нибудь знает, что происходит?Я на 100% уверен, что код, который я выложил здесь, является единственным, который вызывается во время этого процесса, и я не могу честно понять, почему процесс должен завершиться неудачей, если оба запроса возвращают данные

1 Ответ

0 голосов
/ 30 декабря 2018

Итак, как правильно указал Алон Эйтан в комментариях, ошибка была как-то связана с ui-grid и, возможно, возможно, что gridOptions были названы неправильно, как исключение HTML.
В ФАКТЕ ...

HTML

<div class="alerts container-fluid" ng-controller="AdsController">
        <div class="row">
            WORK IN PROGRESS!
            <!--  <span>Pubblicità attive: <b>{{activeAdsCounter}}</b> - </span>-->
            <!-- <span>Pubblicità totali: <b>{{totalAdsCounter}}</b> - </span>-->
        </div>
        <button ng-click="openCreateNewAdModal()"><i class="material-icons">library_add</i></button>
        <div class="row">
            <div class="col-md-12">
                <h3>Pubblicità Nel Sistema</h3>
                <div class="grid" ui-grid="adsGridOptions" ui-grid-pagination
                    ui-grid-auto-resize></div>
            </div>
        </div>
    </div>


Контроллер

define(['app', 'moment'], function (app, moment) {

    app.controller('AdsController', AdsController);
    AdsController.$inject = ['$scope', '$mdDialog', 'AdvService'];

    function AdsController($scope, $mdDialog, AdvService) {
        debugger;
        $scope.rowHeight = 30;
        $scope.gridOptions = {
            data: 'searchRes',
            paginationPageSizes: [25, 50, 75],
            paginationPageSize: 25,
            enableSorting: true,
            enablePaginationControls: true,
            enableColumnMenus: false,
            useExternalPagination: true,
            rowHeight: $scope.rowHeight,
            columnDefs: [
                 {
                    name: 'Cliente',
                    field: 'customerName',
                }, {
                    name: 'Durata',
                    field: 'duration',
                },  {
                    name: 'Euro Spesi',
                    field: 'spentEuros',
                },  {
                    name: 'Data inserimento',
                    field: 'createdAt',
                    type: 'date',
                    width: '130',
                    cellFilter: "date:'dd-MM-yyyy'",
                },  {
                    name: 'Email Referente',
                    field: 'referralEmail',
                },  {
                    name: 'Nome Referente',
                    field: 'referralPerson',
                },  {
                    name: 'Numero Referente',
                    field: 'referralNumber',
                },
            ],
            onRegisterApi: function (gridApi) {
                $scope.gridApi = gridApi;
                $scope.gridApi.core.on.sortChanged($scope, function (grid, sortColumns) {
                    if (sortColumns[0]) {
                        console.log(sortColumns[0].sort);
                        $scope.searchCriteria.sort = {};
                        $scope.searchCriteria.sort[sortColumns[0].field] = sortColumns[0].sort.direction;
                    }
                });
                $scope.gridApi.pagination.on.paginationChanged($scope, function (pageNum, pageSize) {
                    $scope.searchCriteria.pageNumber = pageNum;
                    $scope.searchCriteria.pageSize = pageSize;
                    $scope.search();
                });
            }
        };

Контроллер имел опции, называемые «gridOptions», в то время как в HTML они назывались «adsGridOptions».Изменение имени на «gridOptions» для обеих сторон решило проблему.

Спасибо, Алон Эйтан!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...