Nedomas/databound

View on GitHub
doc/src/databound.html

Summary

Maintainability
Test Coverage
<!DOCTYPE html><html lang="en"><head><title>src/databound</title></head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><meta name="groc-relative-root" content="../"><meta name="groc-document-path" content="src/databound"><meta name="groc-project-path" content="src/databound.coffee"><link rel="stylesheet" type="text/css" media="all" href="../assets/style.css"><script type="text/javascript" src="../assets/behavior.js"></script><body><div id="meta"><div class="file-path">src/databound.coffee</div></div><div id="document"><div class="segment"><div class="code"><div class="wrapper">_ = <span class="hljs-built_in">require</span> <span class="hljs-string">'lodash'</span>
jQuery = <span class="hljs-built_in">require</span> <span class="hljs-string">'jquery'</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>You can specify scope for the connection.</p>
<pre><code class="lang-coffeescript">  User = <span class="hljs-keyword">new</span> Databound <span class="hljs-string">'/users'</span>, <span class="hljs-attribute">city</span>: <span class="hljs-string">'New York'</span>

  User.where(<span class="hljs-attribute">name</span>: <span class="hljs-string">'John'</span>).<span class="hljs-keyword">then</span> (users) -&gt;
    alert <span class="hljs-string">'You are a New Yorker called John'</span>

  User.create(<span class="hljs-attribute">name</span>: <span class="hljs-string">'Peter'</span>).<span class="hljs-keyword">then</span> (new_user) -&gt;
    <span class="hljs-comment"># I am from New York</span>
    alert <span class="hljs-string">"I am from <span class="hljs-subst">#{new_user.city}</span>"</span></code></pre></div></div><div class="code"><div class="wrapper"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Databound</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@endpoint</span>, <span class="hljs-property">@scope</span> = {}, <span class="hljs-property">@options</span> = {})</span> -&gt;</span>
    <span class="hljs-property">@extra_where_scopes</span> = <span class="hljs-property">@options</span>.extra_where_scopes <span class="hljs-keyword">or</span> []
    <span class="hljs-property">@records</span> = []
    <span class="hljs-property">@seeds</span> = []
    <span class="hljs-property">@properties</span> = []</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><h2 id="start-of-configs">Start of Configs</h2>
<p>Functions <code>request</code> and <code>promise</code> are overritable</p></div></div><div class="code"><div class="wrapper">  Databound.API_URL = <span class="hljs-string">""</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>Does a POST request and returns a <code>promise</code></p></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">request</span>: <span class="hljs-function"><span class="hljs-params">(action, params)</span> -&gt;</span>
    jQuery.post <span class="hljs-property">@url</span>(action), <span class="hljs-property">@data</span>(params), <span class="hljs-string">'json'</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>Returns a <code>promise</code> which resolves with <code>result</code></p></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">promise</span>: <span class="hljs-function"><span class="hljs-params">(result)</span> -&gt;</span>
    deferred = jQuery.Deferred()
    deferred.resolve result
    deferred.promise()</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><h2 id="end-of-configs">End of Configs</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper">  <span class="hljs-attribute">where</span>: <span class="hljs-function"><span class="hljs-params">(params)</span> -&gt;</span>
    _this = @

    <span class="hljs-property">@wrappedRequest</span>(<span class="hljs-string">'where'</span>, params).<span class="hljs-keyword">then</span> (resp) -&gt;
      records = JSON.parse(resp.records).concat(_this.seeds)
      _this.records = _.sortBy(records, <span class="hljs-string">'id'</span>)
      _this.promise _this.records

  <span class="hljs-attribute">all</span>: <span class="hljs-function">-&gt;</span>
    <span class="hljs-property">@where</span>()</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>Return a single record by <code>id</code></p>
<pre><code class="lang-coffeescript">User.find(<span class="hljs-number">15</span>).<span class="hljs-keyword">then</span> (user) -&gt;
  alert <span class="hljs-string">"Yo, <span class="hljs-subst">#{user.name}</span>"</span></code></pre></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">find</span>: <span class="hljs-function"><span class="hljs-params">(id)</span> -&gt;</span>
    <span class="hljs-property">@checkUndefinedId</span>(<span class="hljs-string">'find'</span>, id)

    _this = @
    <span class="hljs-property">@where</span>(<span class="hljs-attribute">id</span>: id).<span class="hljs-keyword">then</span> -&gt;
      record = _this.take(id)

      <span class="hljs-keyword">unless</span> record
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> DataboundError(<span class="hljs-string">"Couldn't find record with id: <span class="hljs-subst">#{id}</span>"</span>)

      _this.promise record</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>Return a single record by <code>params</code></p>
<pre><code class="lang-coffeescript">User.findBy(<span class="hljs-attribute">name</span>: <span class="hljs-string">'John'</span>, <span class="hljs-attribute">city</span>: <span class="hljs-string">'New York'</span>).<span class="hljs-keyword">then</span> (user) -&gt;
  alert <span class="hljs-string">"I'm John from New York"</span></code></pre></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">findBy</span>: <span class="hljs-function"><span class="hljs-params">(params)</span> -&gt;</span>
    _this = @

    <span class="hljs-property">@where</span>(params).<span class="hljs-keyword">then</span> (resp) -&gt;
      _this.promise _.first(_.values(resp))

  <span class="hljs-attribute">create</span>: <span class="hljs-function"><span class="hljs-params">(params)</span> -&gt;</span>
    <span class="hljs-property">@requestAndRefresh</span> <span class="hljs-string">'create'</span>, params</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>Specify <code>id</code> when updating or destroying the record.</p>
<pre><code class="lang-coffeescript">  User = <span class="hljs-keyword">new</span> Databound <span class="hljs-string">'/users'</span>

  User.update(<span class="hljs-attribute">id</span>: <span class="hljs-number">15</span>, <span class="hljs-attribute">name</span>: <span class="hljs-string">'Saint John'</span>).<span class="hljs-keyword">then</span> (updated_user) -&gt;
    alert updated_user

  User.destroy(<span class="hljs-number">15</span>).<span class="hljs-keyword">then</span> (resp) -&gt;
    alert resp.success</code></pre></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">update</span>: <span class="hljs-function"><span class="hljs-params">(params)</span> -&gt;</span>
    <span class="hljs-property">@requestAndRefresh</span> <span class="hljs-string">'update'</span>, params

  <span class="hljs-attribute">destroy</span>: <span class="hljs-function"><span class="hljs-params">(id)</span> -&gt;</span>
    <span class="hljs-property">@checkUndefinedId</span>(<span class="hljs-string">'destroy'</span>, id)
    <span class="hljs-property">@requestAndRefresh</span> <span class="hljs-string">'destroy'</span>, <span class="hljs-attribute">id</span>: id</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>Just take already dowloaded records</p></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">take</span>: <span class="hljs-function"><span class="hljs-params">(id)</span> -&gt;</span>
    _.detect <span class="hljs-property">@records</span>, <span class="hljs-function"><span class="hljs-params">(record)</span> -&gt;</span>
      id.toString() == record.id.toString()

  <span class="hljs-attribute">takeAll</span>: <span class="hljs-function">-&gt;</span>
    <span class="hljs-property">@records</span></div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>f.e. Have default records</p></div></div><div class="code"><div class="wrapper">  <span class="hljs-attribute">injectSeedRecords</span>: <span class="hljs-function"><span class="hljs-params">(records)</span> -&gt;</span>
    <span class="hljs-property">@seeds</span> = records

  <span class="hljs-attribute">requestAndRefresh</span>: <span class="hljs-function"><span class="hljs-params">(action, params)</span> -&gt;</span>
    _this = @</div></div></div><div class="segment"><div class="comments "><div class="wrapper"><p>backend responds with:</p>
<pre><code class="lang-javascript">  {
    success: <span class="hljs-literal">true</span>,
    id: record.id,
    scoped_records: []
  }</code></pre></div></div><div class="code"><div class="wrapper">    <span class="hljs-property">@wrappedRequest</span>(action, params).<span class="hljs-keyword">then</span> (resp) -&gt;
      records = JSON.parse(resp.scoped_records)
      records_with_seeds = records.concat(_this.seeds)
      _this.records = _.sortBy(records_with_seeds, <span class="hljs-string">'id'</span>)

      <span class="hljs-keyword">if</span> resp.id
        _this.promise _this.take(resp.id)
      <span class="hljs-keyword">else</span>
        _this.promise resp.success

  <span class="hljs-attribute">url</span>: <span class="hljs-function"><span class="hljs-params">(action)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> _.isEmpty(Databound.API_URL)
      <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@endpoint</span>}</span>/<span class="hljs-subst">#{action}</span>"</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-string">"<span class="hljs-subst">#{Databound.API_URL}</span>/<span class="hljs-subst">#{<span class="hljs-property">@endpoint</span>}</span>/<span class="hljs-subst">#{action}</span>"</span>

  <span class="hljs-attribute">data</span>: <span class="hljs-function"><span class="hljs-params">(params)</span> -&gt;</span>
    <span class="hljs-attribute">scope</span>: JSON.stringify(<span class="hljs-property">@scope</span>)
    <span class="hljs-attribute">extra_where_scopes</span>: JSON.stringify(<span class="hljs-property">@extra_where_scopes</span>)
    <span class="hljs-attribute">data</span>: JSON.stringify(params)

  <span class="hljs-attribute">wrappedRequest</span>: <span class="hljs-function"><span class="hljs-params">(args...)</span> -&gt;</span>
    <span class="hljs-property">@request</span>(args...).<span class="hljs-keyword">then</span>(_.bind(<span class="hljs-property">@handleSuccess</span>, @)).fail(<span class="hljs-property">@handleFailure</span>)

  <span class="hljs-attribute">handleSuccess</span>: <span class="hljs-function"><span class="hljs-params">(resp)</span> -&gt;</span>
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">'Error in the backend'</span> <span class="hljs-keyword">unless</span> resp?.success

    <span class="hljs-property">@promise</span>(resp)

  <span class="hljs-attribute">handleFailure</span>: <span class="hljs-function"><span class="hljs-params">(e)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> e.status == DataboundError.STATUS
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> DataboundError(e.responseJSON.message)
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"Error in the backend with status <span class="hljs-subst">#{e.status}</span>"</span>

  <span class="hljs-attribute">checkUndefinedId</span>: <span class="hljs-function"><span class="hljs-params">(action, id)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> _.isUndefined(id)

    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> DataboundError(<span class="hljs-string">"Couldn't <span class="hljs-subst">#{action}</span> a record without an id"</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataboundError</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(text)</span> -&gt;</span>
    <span class="hljs-property">@message</span> = <span class="hljs-string">"Databound: <span class="hljs-subst">#{text}</span>"</span>

  <span class="hljs-property">@STATUS</span>: <span class="hljs-number">405</span>

<span class="hljs-attribute">DataboundError</span>:: = <span class="hljs-keyword">new</span> Error()

<span class="hljs-built_in">module</span>.exports = Databound</div></div></div></div></body></html>