0

I am building a form that can send and clear cached JSON data using AngularJS to a RESTful web service. When I click submit, the current form data is cached in a JSON object, I then send that data through the web service. Once it is sent I clear the cache.

I have a function I wish to use in multiple controllers (sending cached data). It loops through the cache, sending each JSON object one at a time. When I have the function in a single controller, the code works fine. But once I wrap it in a service and call it in through a controller, my loop no longer works. It runs fine if there is only 1 cache object. But if there are more than 1, the "this.sendCache()" will not fire. I believe this has something to do with the asynchronous function and am not sure what to do about it. Help is greatly appreciated!!!

Controller

app.controller('FormCtrl', function($scope, $filter, $window, getData, Post, randomString, $cordovaProgress, $cordovaDialogs, scService) {

    $scope.submitEntry = function() {

        var frmData = new Post($scope.postData);
        var postCount = window.localStorage.getItem("localPostCount");
        postCount ++;

        window.localStorage.setItem("localPostCount", postCount);
        window.localStorage.setItem("post" + postCount, JSON.stringify(frmData));

        scService.sendCache();

    };

});

Service

app.service('scService', function ($window, Post, $cordovaProgress, $cordovaDialogs, $timeout) {

    this.sendCache = function () {
        if(window.Connection){
            if(navigator.connection.type != Connection.NONE) {

                var postCount = window.localStorage.getItem("localPostCount");
                var curCacheObj = new Post(JSON.parse(window.localStorage.getItem("post" + postCount) || '{}'));

                if (postCount > 0) {
                    curCacheObj.$save().then(function(response) {
                        var servResponse = JSON.stringify(response);
                            if (servResponse.indexOf("@xmlns:ns3") > -1) {
                                console.log("Post " + postCount + " sent!");
                            }
                            else {
                                console.log("Unable to post at this time!");
                            }
                        }).then(function() {
                            window.localStorage.removeItem("post" + postCount);
                            postCount --;
                            window.localStorage.setItem("localPostCount", postCount);
                        }).then(function() {
                            console.log(postCount); //log shows 1
                            if (postCount > 0) {
                                    this.sendCache(); //yet this won't fire again!
                                }
                                else {
                                    $cordovaDialogs.alert('Submission recorded successfully', 'Success', 'OK').then(function() {
                                      console.log('Submission Success');
                                      $window.location.href= 'index.html';
                                    });
                                }
                    });
                }
                else {
                $cordovaDialogs.alert('Submission recorded successfully', 'Success', 'OK').then(function() {
                  console.log('Submission Success');
                  $window.location.href= 'index.html';
                });
                }
            }
            else {
                $cordovaDialogs.alert('Your current connection is too slow. Sync at a later time by returning to the app with a better connection.', 'Submission Stored', 'OK').then(function() {
                  console.log('Submission Cached');
                  $window.location.href= 'index.html';
                });
            }
        }
    };

});

1 Answer 1

1

It is actually a very common JS issue, and not related to AngularJS itself. this is not what you think it is. Inside the .then() callback, your context has changed so it is no longer pointing to your service but to the response context from the async call. Therefore, the function sendCache() does not actually exist and cannot be called that way.

All you need to do is take a reference to self at the top of your service:

var self = this;

Then use self instead of this in your call:

self.sendCache();

Note that this is not causing trouble for you with variables like postCount because they're locally defined within the closure and do not require this to be referenced. But if you were to define this.postCount or other variables in your service, you would need to do the same thing.

Sign up to request clarification or add additional context in comments.

2 Comments

OMG IT WORKS I LOVE YOU! Seriously though, I would never have figured that out on my own
Don't feel bad. I knew the answer because I've done exactly the same thing, LOL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.