title: How to resolve javascript "not a function" error
body: <p>Receiving error: <strong><em>Uncaught TypeError: follow(...).then(...).done is not a function</em></strong></p>
  <p><a href="https://i.stack.imgur.com/jGuCm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jGuCm.png" alt="enter image description here" /></a></p>
  <p>This is the code block in question in <em>app.js</em>:</p>
  <pre><code>class App extends React.Component {
      constructor(props) {
          super(props)
          this.state = {customRectangles: []};
      }
  
      loadFromServer(pageSize) {
          follow(client, root, [
              {rel: 'customRectangles', params: {size: pageSize}}]
          ).then(rectangleCollection =&gt; {
              return client({
                  method: 'GET',
                  path: rectangleCollection.entity._links.profile.href,
                  headers: {'Accept': 'application/schema+json'}
              }).then(schema =&gt; {
                  this.schema = schema.entity;
                  return rectangleCollection;
              });
          }).done(rectangleCollection =&gt; {
              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 (
              &lt;RectangleList customRectangles={this.state.customRectangles}/&gt;
          )
      }
  }
  </code></pre>
  <p>And here is my <em>follow.js</em> file:</p>
  <pre><code>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 &amp;&amp; entity._embedded.hasOwnProperty(rel);
      }
  };
  </code></pre>
  <p>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!</p>
  <hr>
  <h2>Resolved</h2>
  <p>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 <code>follow</code> func:</p>
  <pre><code>module.exports = function follow(api, rootPath, relArray) {
      var self = this;
      return new Promise(function (self) {
          var root = api({
              method: 'GET',
              path: rootPath
          });
      //...
  </code></pre>
  <p>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: <a href="https://stackoverflow.com/questions/23772801/basic-javascript-promise-implementation-attempt">Basic Javascript promise implementation attempt</a></p>
  <p>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</p>