0

Receiving error: Uncaught TypeError: follow(...).then(...).done is not a function

enter image description here

This is the code block in question in app.js:

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {customRectangles: []};
    }

    loadFromServer(pageSize) {
        follow(client, root, [
            {rel: 'customRectangles', params: {size: pageSize}}]
        ).then(rectangleCollection => {
            return client({
                method: 'GET',
                path: rectangleCollection.entity._links.profile.href,
                headers: {'Accept': 'application/schema+json'}
            }).then(schema => {
                this.schema = schema.entity;
                return rectangleCollection;
            });
        }).done(rectangleCollection => {
            this.setState({
                customRectangles: rectangleCollection.entity._embedded.customRectangles,
                attributes: Object.keys(this.schema.properties),
                pageSize: pageSize,
                links: rectangleCollection.entity._links});
        });
    }

    componentDidMount() {
        this.loadFromServer(this.state.pageSize);
    }

    render() {
        return (
            <RectangleList customRectangles={this.state.customRectangles}/>
        )
    }
}

And here is my follow.js file:

module.exports = function follow(api, rootPath, relArray) {
    var root = api({
        method: 'GET',
        path: rootPath
    });

    return relArray.reduce(function(root, arrayItem) {
        var rel = typeof arrayItem === 'string' ? arrayItem : arrayItem.rel;
        return traverseNext(root, rel, arrayItem);
    }, root);

    function traverseNext (root, rel, arrayItem) {
        return root.then(function (response) {
            if (hasEmbeddedRel(response.entity, rel)) {
                return response.entity._embedded[rel];
            }

            if(!response.entity._links) {
                return [];
            }

            if (typeof arrayItem === 'string') {
                return api({
                    method: 'GET',
                    path: response.entity._links[rel].href
                });
            } else {
                return api({
                    method: 'GET',
                    path: response.entity._links[rel].href,
                    params: arrayItem.params
                });
            }
        });
    }

    function hasEmbeddedRel (entity, rel) {
        return entity._embedded && entity._embedded.hasOwnProperty(rel);
    }
};

I think I've been looking at this one for a little too long at this point, I would really appreciate any assistance with the code adjustment necessary to resolve this. Just let me know if you need any more info, thank you!


Resolved

The solution was as @sorja stated, except that I needed it to take a function and and return a Promise/ object. And there were challenges for me with the .then() and .done(). Ultimately the above code only changed by 2 lines in the follow func:

module.exports = function follow(api, rootPath, relArray) {
    var self = this;
    return new Promise(function (self) {
        var root = api({
            method: 'GET',
            path: rootPath
        });
    //...

I'm not sure whether this was a truly async setup or if I could have gotten away with a mock Promise, but I implemented the Promise state machine outlined here: Basic Javascript promise implementation attempt

Learned a lot and it works great so it's all good either way. Quality info on the set up from @ForbesLindesay and also from @trincot

Community
  • 1
  • 1
TheBlackKeys
  • 852
  • 1
  • 9
  • 15

1 Answers1

3

You are trying to call 'then' function of object 'follow'. But the problem is, that 'follow' is a function, instead of a Promise (/object).

You can try to wrap the function around a new Promise like so:

module.exports = new Promise(function(resolve, reject) {
  if(all ok) {
    resolve(params)
  } else {
    reject(params)
  }
});

For more information about Promises, see MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

sorja
  • 52
  • 2
  • I settled on: `module.exports = function follow(api, rootPath, relArray) { var self = this; return new Promise(function (self) { var root = api({ method: 'GET', path: rootPath });` Just 2 lines added to the function. Well, after implementing the whole Promise state machine anyway using this _super_ good info: https://stackoverflow.com/questions/23772801/basic-javascript-promise-implementation-attempt It was probably overkill but whatever it works, appreciate it. – TheBlackKeys Feb 17 '18 at 14:29