1

I am caching my ajax requests using a service worker. So for an initial content load of the page, I am making two asynchronous calls for fetching the data: one to the cache and one to the network. There is a common update function which updates the view by checking the timestamp. However, I am getting a response of undefined for an object property timestamp for the cached response. However, it is definitely defined and can be verified when I check the console. This results in the timestamp check resulting in false and the view is not updated.

Here is my code:

if(angular.isUndefined($scope.userStamp))
{
   $scope.userStamp = 0;
}

if(response.timestamp > $scope.userStamp)
{       
console.log('Update user done');
console.log(source);
console.log(response.timestamp);
console.log($scope.userStamp);
console.log(response);
$scope.user_id=response.user_id;
$scope.username=response.username;
$scope.firstname=response.firstname;            
$scope.lastname=response.lastname;
$scope.email=response.email;
$scope.mobile=response.mobile;
$scope.userStamp = response.timestamp;
}
else
{
console.log('Update user not done');
console.log(source);
console.log(response.timestamp);//returns undefined
console.log($scope.userStamp);
console.log(response);//clearly exists here         
}

**A similar question can be found here: Can't access object property, even though it exists. Returns undefined . But the answers only concern the working of console.log. It doesn't help me with making my code work

Screenshot of the console: Here is the entire code:

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope,$http,$q) {

$scope.updateUser = function(response,source) {
        if(angular.isUndefined($scope.userStamp))
        {
            $scope.userStamp = 0;           
        }
        if(response.timestamp > $scope.userStamp)
        {       
        console.log('Update user done');
        console.log(source);
        console.log(response.timestamp);
        console.log($scope.userStamp);
        console.log(response);
        $scope.user_id=response.user_id;
        $scope.username=response.username;
        $scope.firstname=response.firstname;            
        $scope.lastname=response.lastname;
        $scope.email=response.email;
        $scope.mobile=response.mobile;
        $scope.userStamp = response.timestamp;
        }
        else
        {
        console.log('Update user not done');
        console.log(source);
        console.log(response.timestamp);
        console.log($scope.userStamp);
        console.log(response);          
        }
    }

$scope.getUserNetwork = function(){
    var q = $q.defer(); 

    $http({
        url: '/getData/getUser.php',
        method: "POST"
    })
    .then(function(response) {
        if(response.data.valid)
        {
            $scope.updateUser(response.data,"network");
            console.log('User network complete');
            q.resolve('User network complete');
        }
        else
        {
            console.log('User network not complete');
            console.log(response);
            q.resolve('User network not complete');
        }

    }, 
    function(response) { 
        console.log('User network not complete');
        q.reject('User network not complete');
    }); 
    return q.promise;   
}   

$scope.getUserLocal = function() {  
    var q = $q.defer();

    getLocalData('/getData/getUser.php').then(
    function(data)
    {
        if(data.msg=="success")
        {
            console.log('Get local user success!');
            console.log(data);
            $scope.updateUser(data.cachedata,"local");
            q.resolve('User network complete');         
        }
        else
        {
            q.resolve('User network complete');
        }           
    },
    function(msg)
    {
        console.log('Get local user falied!');
        console.log(msg);
        q.reject('User local not complete');
    }
    );

    return q.promise;
    }

$scope.updateProducts = function(response,source)
    {
        if(angular.isUndefined($scope.productsStamp))
        {
            $scope.productsStamp = 0;           
        }
        if(response.timestamp > $scope.productsStamp)
        {       
        console.log('Update products done');
        console.log(source);
        console.log(response.timestamp);
        console.log($scope.productsStamp);
        console.log(response);
        $scope.products=response.products;      
        $scope.productsStamp = response.timestamp;      
        }
        else
        {
        console.log('Update products not done');
        console.log(source);
        console.log(response.timestamp);
        console.log($scope.productsStamp);
        console.log(response);          
        }
    }   

$scope.getProductsNetwork = function() {
    var q = $q.defer(); 
    $http({
        url: '/getData/getProducts.php',
        method: "POST",
        data: {"user_id":$scope.user_id}
    })
    .then(function(response) {
        if(response.data.valid)
        {
            console.log('Products network complete');
            console.log(response.data.products);
            $scope.updateProducts(response.data,"network");
            q.resolve('Products network complete');
        }
        else
        {
            console.log('Products network not complete');
            console.log(response);
            q.reject('Products network not complete');
        }
    }, 
    function(response) {
        console.log('Products network not complete');   
        console.log(response);      
        q.reject('Products network not complete');
    });
    return q.promise;               
    }

$scope.getProductsLocal = function() {
    var q = $q.defer();
    getLocalData('/getData/getProducts.php').then(  
    function(data)
    {
        if(data.msg=="success")
        {
            console.log('Get local product success!');
            console.log(data);
            $scope.updateProducts(data.cachedata,"local");
            q.resolve('Products local complete');           
        }
        else
        {
            q.resolve('Products local complete');
        }
    },
    function(msg)
    {
        console.log('Get local product falied!');
        console.log(msg);
        q.reject('Products local not complete');
    }   
    );
    return q.promise;
    }

    angular.element(document).ready(function () {
        $scope.getUserLocal().then(function(msg){$scope.getProductsLocal().then(function(msg){$scope.getUserNetwork().then(function(msg){$scope.getProductsNetwork();
        });
        });
        });     
    }); 

});   

function getLocalData(url)
{
     return new Promise(function(resolve, reject) {
     if ('caches' in window)
     {
      base_url="https://milk-test.000webhostapp.com";
      caches.match(base_url+url).then(function(response) {
        if (response) {
            console.log('Local data found');
            resolve({msg:'success',cachedata:response.json()});
        }
        else
        {
            console.log('Local data not found');
            resolve({msg:'fail'});
        }
      },
      function(msg)
      {
          console.log(msg);
          reject('getLocalData Failed');
      }
      );
    }
     });
}
  • can i see the promise you used to get the data .. and where you have written the console log? – Shayuh Jun 22 '17 at 07:40
  • Hard to see without more code... But use the promise `.then` handler to wait for your promise resolvement. See more about promises at https://docs.angularjs.org/api/ng/service/$q – daan.desmedt Jun 22 '17 at 07:42
  • I am using the .then handler. I ll put the relevant code and edit the post – Karan Saini Jun 22 '17 at 07:52
  • Can you share `getLocalData` methods response json directly stringified? – Burak Akyıldız Jun 22 '17 at 08:04
  • it is there in the screenshot. it is the expanded object. – Karan Saini Jun 22 '17 at 08:06
  • In the screen shot you are showing a promise value. It can be later declared. And promise value logged before `resolve` of `getLocalData` function. Chromes console is mistaking you. – Burak Akyıldız Jun 22 '17 at 08:10
  • so what exactly am I doing wrong here? The undefined occurs only for the cached response when I load the page. Any further data fetches on the page which are via network work perfectly. – Karan Saini Jun 22 '17 at 08:31

1 Answers1

0

I solved the problem. The problem was with the json() function. I found the solution here:

Why does .json() return a promise if in an object literal?

Instead of calling json() inside the resolve call, I passed the response object as it is and later called json() in the next function in the chain.

        data.cachedata.json().then(
        function(data)
        {
            $scope.updateUser(data,"local");
        },
        function(msg)
        {
            console.log(msg);
        }
        );