0

I'm trying return the data from the function 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) {  });
    }

and want to pass it to the next function insertDaysHtml where I want iterate it and fetch data of the ShiftDetails as below but getting errors as below .

 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);
    }
user11130182
  • 121
  • 10

3 Answers3

0

getShiftDetails is doing an asynchronous call using Promise. You can read about how Promise and async in JavaScript works for clarification. But to answer your question,

ShiftDtls = getShiftDetails();

If you see the body of the function getShiftDetails, it is not returning anything. So, you get undefined.

To make it work, do your thing inside successCallback instead of returning the value.

Jayendra Sharan
  • 1,043
  • 6
  • 10
0

First of all, you are not returning anything from getShiftDetails() function. So, you need to add a return statement like this:

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) {});
}

Secondly, your getShiftDetails() function is doing an asynchronous call using Promise. Therefore below statement is executed before getting data

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

So, one possible solution is call the insertDaysHtml() function from your resolved request function. Like this:

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) {});
}

Hope, this will help you. Thanks!

Adnan Sharif
  • 919
  • 7
  • 17
  • I think you're asking me to call the insertDaysHtml(response.data); inside getShiftDetails after successcallback. Even after that I'm getting Cannot read property 'length' of undefined at for (var j = 0; j <= ShiftDtls.length; j++) {. – user11130182 Apr 02 '19 at 08:23
  • @user11130182 are you calling `insertDaysHtml()` function from other parts of your code? Have your removed `insertDaysHtml(ShiftDtls); ` from your code before testing it? – Adnan Sharif Apr 02 '19 at 08:27
0

To understand what happens imagine the HTTP get doing a long run, instead of doing a circle on your localhost, it takes a lot of time. In javascript this is made possible with the async call, so the program is not blocked while waiting for the response, and when the response finally there, it is handled in a so called callback function. To force the controller to wait for the response you have to use Promises.

// 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;
  });
}

Another thing i must note: the line in your code:

return ShiftDetails;

It's gravely wrong, you are trying to return from a function inside a function. In javascript there is a lot of callback function, they are not easy to keep clean, but you have to learn more about them, because, they really help. They are not called by you, so if you try to return from them, their response is not caught by your variables though, the only reason where you want to return from a callback function, is if you want to stop the execution in a point, for example, if you are using a forEach function, for finding the first element in an array with a condition, you don't want to check the elements after you found the first one that meets the condition, something like this:

var first;
elements.forEach(function(element) {
  if(isFirst(element)){
    first = element;
    return;
  }
});
Zarna Borda
  • 695
  • 1
  • 6
  • 22