AngularJS .then по обещанию -> не может прочитать свойство null / undefined - PullRequest
0 голосов
/ 03 июля 2018

У меня есть вопрос о директивах и методе .then.
Вот мой код контроллера (я использую его для передачи переменных в мою директиву):

angular
    .module('thermofluor')
    .controller('ExperimentsController', ExperimentsController)


    ExperimentsController.$inject = ['$state', '$stateParams', 'PlatesService', '$timeout', '$q', '$scope'];

    function ExperimentsController($state, $stateParams, PlatesService, $timeout, $q, $scope) {
    var exp = this;
    //console.log($stateParams);
    exp.barcode = $stateParams.barcode;
    exp.plate = $stateParams.plate;
    exp.current_user = "";
    exp.users = [];
    exp.curves = [];
    exp.summary = [];
    exp.selected_wells = [];

    // liste experiments
    console.log($stateParams.id);
    getPlateById($stateParams.id);

    function getUsers()
    {
        $timeout(function() {
            exp.users = PlatesService.customShow(exp.plate.id, "users")
                .then(getUsers)
                .catch(getUsersFailed);

            function getUsers ( data ) {
                exp.users = data[0];
                return exp.users;
            }

            function getUsersFailed ( e ) {
                var newMessage = 'Failed To Retrieve the users';
                if (e.data && e.data.description) {
                    newMessage = newMessage + '\n' + e.data.description;
                }
                console.log( e );
                e.data = newMessage;
                return $q.reject(e);
            }

        });
    }

    function getPlateById(id)
    {
        $timeout(function() {
            exp.plate = PlatesService.show(id)
                .then(getPlate)
                .catch(getPlateFailed);

            function getPlate ( data ) {
                exp.plate = data;
                exp.curves[exp.plate.experiments[0].well] = [exp.plate.experiments[0].points, exp.plate.experiments[0].tm];
                getUsers();
                return exp.plate;
            }

            function getPlateFailed ( e ) {
                var newMessage = 'Failed To Retrieve the plate';
                if (e.data && e.data.description) {
                    newMessage = newMessage + '\n' + e.data.description;
                }
                console.log( e );
                e.data = newMessage;
                return $q.reject(e);
            }
        });
    }
}

1 - у меня есть простая директива:

angular
    .module('thermofluor')
    .directive('legend', legend)

    legend.$inject = ['$timeout', '$q'];

    function legend($timeout, $q) {
    var directive = {
        link: link,
        restrict: 'E',
        templateUrl: '/crims/thermofluor/experiments/legend.html',
        scope: {
            selected_wells: '=',
            current_user: '=',
            plate: '='
        }
    };

    return directive;

    function link(scope, element) {
        console.log("TESTT");
        console.log(scope);

        scope.plate.then(function (res) {
           console.log(scope.selected_wells);
        });
    }
}

Я не понимаю, почему selected_wells и current_user пусты, а тарелка не пуста. А также почему иногда у меня возникает одна из этих двух ошибок:

TypeError: Cannot read property 'then' of null
TypeError: Cannot read property 'then' of undefined

Я думаю, это потому, что планшет еще не загружен (загружается с помощью вызова ajax), но это не утилита .then для запуска функции после загрузки объекта?

Edit:

Вот PlateService (я использую restangular):

angular.module('thermofluor')
.factory( 'PlatesService', PlatesService);

PlatesService.$inject = ['Restangular', 'RepositoryService', '$cacheFactory', 'tmConfig', 'tmCache'];


function PlatesService( Restangular, RepositoryService, $cacheFactory, tmConfig, tmCache )
{
RepositoryService.extend( PlatesService )

return new PlatesService();

function PlatesService()
{
    var service = this;
    var cache = tmCache.plates();

    //Restangular.setDefaultRequestParams({api_token: ChiefService.getCurrentToken()});

    RepositoryService.call(service, Restangular.withConfig( config ), 'plates',  cache );

    return service;


    function config( RestangularConfigurer )
    {
        Restangular.setDefaultHttpFields({cache: cache});

        return RestangularConfigurer.setBaseUrl(tmConfig.api);
    }

}
* *} Тысяча двадцать-один

И этот сервис использует этот RepositoryService

function RepositoryService( $cacheFactory)
{

RepositoryService.prototype = {
    all:all,
    filterAll:filterAll,
    show:show,
    customShow:customShow,
    store:store,
    update:update,
    destroy:destroy,
    restore:restore,
};

RepositoryService.extend = function (repository) {
    repository.prototype = Object.create(RepositoryService.prototype);
    repository.prototype.constructor = repository;
};

return RepositoryService;

function RepositoryService(restangular, route, cache)
{
    console.log( cache );
    this.restangular = restangular;
    this.route = route;
    this.cache = cache;

}

function all()
{
    return this.restangular.all(this.route).getList();
}

function filterAll( filters )
{
    return this.restangular.all(this.route).customGETLIST('', filters );
}

function show(uuid)
{
    return this.restangular.one(this.route, uuid ).get();
}

function customShow(uuid, extend)
{
    return this.restangular.one(this.route, uuid).customGET( extend );
}

function store( resource )
{
    clear( this.cache );
    return this.restangular.all(this.route).post( resource );
}

function update( resource )
{
    clear( this.cache );
    return this.restangular.one(this.route, resource.uuid).customPUT( resource );
}

function destroy( resource )
{
    clear( this.cache );
    return this.restangular.one(this.route, resource.uuid).remove();
}

function restore( resource )
{
    clear( this.cache );
    return this.restangular.all(this.route + '/' + resource.uuid + '/restore' ).post();
}

function clear( cache )
{
   if(_.isUndefined( cache )) {
       return;
   }
   cache.removeAll();
}

}
...