Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting ".then() is not a function" error when using AngularJS

This is my JS:

self.obj = {}
self.obj.accessErrors = function(data) {
    var cerrorMessages = [];
    for (prop in data) {
        if (data.hasOwnProperty(prop)){
            if (data[prop] != null && data[prop].constructor ==  Object) {
                self.obj.fetch[accessErrors](data[prop]);
            }
            else {
                cerrorMessages.push(data[prop]);
            }
        }
    }
    return cerrorMessages;
};

self.obj.fetch = {
    X: function() {
        // do stuff.
    },

    Y: function(callback) {
        $http.get('/yposts/').then(
            function(response) {
                self.posts = response.data;
                callback(self.posts);
            },
            function(response) {
                self.posts = {};

                self.obj.accessErrors(response.data).then(function(cerrrorMessages) {
                    callback(posts, cerrorMessages);
                });
            }
        );
    }
};

And I am getting an error pointing to this line:

self.obj.accessErrors(response.data).then(function(cerrrorMessages) {

The error says:

TypeError: self.obj.accessErrors(...).then is not a function

Any idea how to solve this?

like image 687
SilentDev Avatar asked Nov 21 '15 00:11

SilentDev


2 Answers

self.obj.accessErrors(response.data) does not return a promise so therefore, you can't use promise methods on it.

If you want it to return a promise and you want that promise to reflect when all the fetch() operations are done and those operations are actually async, then you will have to make all your async code into using promises and you will have to combine them all using Promise.all() or the angular equivalent and convert from using callbacks in fetch to just using a promise. Right now, you have a mix which is difficult to program with.

like image 188
jfriend00 Avatar answered Nov 07 '22 12:11

jfriend00


The .then() construction is only needed when using Promise objects - essentially, instead of returning a value, the function returns an object that resolves to a value at some point in the future (which is then passed into the function that you pass to .then().

But you are right in that you need an asynchronous pattern to do this correctly, since fetch.Y is an asynchronous method. A good thing to do would be to create an array of promises at the beginning of your accessErrors function, like so:

var fetchPromises = [];

and then replace self.obj.fetch[accessErrors](data[prop]); with something that calls push on that array to add the promise that fetch returns to it.

Then, instead of returning accessErrors, return Promise.all(fetchPromises).

This will require some fairly significant modification to your code, however - namely, you will need to rewrite it so that it uses the Promise API instead of this callback by itself (which shouldn't be too difficult to do).

like image 32
TheHans255 Avatar answered Nov 07 '22 10:11

TheHans255