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

3
  • I guess you have to setState inside of then callback may be near then(schema => { this.schema = schema.entity; return rectangleCollection; Commented Feb 17, 2018 at 8:49
  • What is the result when you log typeof follow? Commented Feb 17, 2018 at 8:51
  • It returned function for typeof follow. Commented Feb 17, 2018 at 9:21

1 Answer 1

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

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

1 Comment

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: stackoverflow.com/questions/23772801/… It was probably overkill but whatever it works, appreciate it.

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.