AngularJs не может вернуть данные из функции

Я пытаюсь вернуть данные из функции getShiftDetails()

SS_Mod_App.controller("SS_Ctrl", function ($scope, $http, $location, $window, $sce) {

     var ShiftDetails = []; var ShiftDtls = [];

    ShiftDtls = getShiftDetails();
      //  alert(ShiftDtls);  -->  ShiftDtls undefined
        insertDaysHtml(ShiftDtls);  

function getShiftDetails() {
        $http({
            method: 'GET',
            url: 'http://xxxxx/api/Shift/GetShiftDetails',
            params: { }
            , headers: { 'Content-Type': 'application/json; charset=utf-8', 'dataType': 'json' }
        }).then(function successCallback(response) {
            ShiftDetails = response.data;               --> successful response with data     
            alert(JSON.stringify(ShiftDetails.length));    -->  getting length 21 here
            return ShiftDetails;  
        }, function errorCallback(response) {  });
    }

и хочу передать его следующей функции insertDaysHtml, где я хочу повторить ее и получить данные ShiftDetails, как показано ниже, но получить ошибки, как показано ниже.

 function insertDaysHtml(ShiftDtls) {    
        alert(JSON.stringify($scope.ShiftDetails.length));   --> Length "0" here
    //alert(JSON.stringify(ShiftDtls.length)); Error msg: TypeError: Cannot read property 'length' of undefined
    // if (ShiftDtls.length > 0) {  --> Error msg: TypeError: Cannot read property 'length' of undefined

        if ($scope.ShiftDtls.length > 0) {  
           // alert(ShiftDtls.length );
            dayhtmlContent = dayhtmlContent + '<tr> '
            for (var j = 0; j <= ShiftDtls.length; j++) {
                dayhtmlContent = dayhtmlContent + '<td> $scope.ShiftDtls[ ' + j + '].ShiftName[0]));'                 
            }

        $scope.divHtmlDay = $sce.trustAsHtml(dayhtmlContent);
    }
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

getShiftDetails выполняет асинхронный вызов, используя Promise. Вы можете прочитать о том, как работает Promise и асинхронность в JavaScript, для разъяснения. Но чтобы ответить на ваш вопрос,

ShiftDtls = getShiftDetails();

Если вы видите тело функции getShiftDetails, она ничего не возвращает. Итак, вы получаете undefined.

Чтобы заставить это работать, делайте свое дело внутри successCallback вместо того, чтобы возвращать значение.

Ответ принят как подходящий

Прежде всего, вы ничего не возвращаете из функции getShiftDetails(). Итак, вам нужно добавить оператор return следующим образом:

function getShiftDetails() {
  return $http({
    method: 'GET',
    url: 'http://xxxxx/api/Shift/GetShiftDetails',
    params: {},
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'dataType': 'json'
    }
  }).then(function successCallback(response) {
    ShiftDetails = response.data;
    -- > successful response with data
    alert(JSON.stringify(ShiftDetails.length));
    -- > getting length 21 here
    return ShiftDetails;
  }, function errorCallback(response) {});
}

Во-вторых, ваша функция getShiftDetails() выполняет асинхронный вызов с использованием Promise. Поэтому приведенный ниже оператор выполняется до получения данных

ShiftDtls = getShiftDetails();
//  alert(ShiftDtls);  -->  ShiftDtls undefined
insertDaysHtml(ShiftDtls); 
//this statement is executing before getting data 

Таким образом, одним из возможных решений является вызов функции insertDaysHtml() из вашей разрешенной функции запроса. Так:

function getShiftDetails() {
  $http({
    method: 'GET',
    url: 'http://xxxxx/api/Shift/GetShiftDetails',
    params: {},
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'dataType': 'json'
    }
  }).then(function successCallback(response) {
    ShiftDetails = response.data;
    -- > successful response with data
    alert(JSON.stringify(ShiftDetails.length));
    -- > getting length 21 here
    insertDaysHtml(response.data); //invoke function from here
  }, function errorCallback(response) {});
}

Надеюсь, что это поможет вам. Спасибо!

Я думаю, вы просите меня вызвать метод insertDaysHtml(response.data); внутри getShiftDetails после успешного обратного вызова. Даже после этого я получаю Невозможно прочитать свойство «длина» неопределенного значения для (var j = 0; j <= ShiftDtls.length; j++) {.

user11130182 02.04.2019 10:23

@user11130182 user11130182 вы вызываете функцию insertDaysHtml() из других частей вашего кода? Вы удалили insertDaysHtml(ShiftDtls); из своего кода перед его тестированием?

Adnan Sharif 02.04.2019 10:27

Чтобы понять, что происходит, представьте, что HTTP выполняет длительный цикл вместо того, чтобы делать круг на вашем локальном хосте, это занимает много времени. В javascript это стало возможным благодаря асинхронному вызову, поэтому программа не блокируется в ожидании ответа, а когда ответ наконец получен, он обрабатывается в так называемой функции обратного вызова. Чтобы заставить контроллер ждать ответа, вы должны использовать промисы.

// Service
YearService.getCurrentYearId = function(){
  var defferer = $q.defer();
  $http.get('years')
    .then(function(response){
      deffer = response;
  });
  return defferer.promise;
};
  
 // Controller
function getData(){
  YearService.getYears()
    .then(function(data){
      YearCtrl.years = data;
  });
}

Еще одна вещь, которую я должен отметить: строка в вашем коде:

return ShiftDetails;

Это серьезно неправильно, вы пытаетесь вернуться из функции внутри функции. В javascript очень много callback-функций, их непросто содержать в чистоте, но вам придется узнать о них больше, потому что они действительно помогают. Они не вызываются вами, поэтому, если вы попытаетесь вернуться из них, их ответ не будет пойман вашими переменными, хотя единственная причина, по которой вы хотите вернуться из функции обратного вызова, - это если вы хотите остановить выполнение в точке , например, если вы используете функцию forEach для поиска первого элемента в массиве с условием, вы не хотите проверять элементы после того, как вы нашли первый элемент, удовлетворяющий условию, примерно так:

var first;
elements.forEach(function(element) {
  if (isFirst(element)){
    first = element;
    return;
  }
});

Другие вопросы по теме