Skip to content

Instantly share code, notes, and snippets.

@jfsiii
Created September 1, 2015 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfsiii/6d373dd6af9ecb2c4690 to your computer and use it in GitHub Desktop.
Save jfsiii/6d373dd6af9ecb2c4690 to your computer and use it in GitHub Desktop.
curl -i http://alt.js.org/guide/async/
HTTP/1.1 200 OK
Server: GitHub.com
Content-Type: text/html; charset=utf-8
Last-Modified: Tue, 28 Jul 2015 05:52:35 GMT
Access-Control-Allow-Origin: *
Expires: Tue, 01 Sep 2015 19:42:12 GMT
Cache-Control: max-age=600
Content-Length: 9728
Accept-Ranges: bytes
Date: Tue, 01 Sep 2015 19:32:12 GMT
Via: 1.1 varnish
Age: 0
Connection: keep-alive
X-Served-By: cache-sjc3121-SJC
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1441135932.614218,VS0,VE73
Vary: Accept-Encoding
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fetching Data</title>
<meta name="description" content="A library for managing data within JavaScript applications. Alt is a pure flux implementation that is small, terse, well tested, extremely flexible, and forward thinking.
">
<link rel="canonical" href="http://alt.js.org/guide/async/">
<link rel="alternate" type="application/rss+xml" title="Alt" href="http://alt.js.org/feed.xml" />
<link type="text/css" rel="stylesheet" href="/assets/bootstrap-navbar.css" />
<link type="text/css" rel="stylesheet" href="/assets/lotus.min.css" />
<link type="text/css" rel="stylesheet" href="/assets/prism.min.css" />
<link type="text/css" rel="stylesheet" href="/assets/styles.css" />
</head>
<body>
<nav class="navbar navbar-default sp-horiz-lg">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/"><img src="/assets/alt.png" alt="Alt" width="40" /></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<div id="alt-search-app"></div>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/guide/">Getting Started</a>
</li>
<li class="dropdown">
<a href='#' class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">API Documentation <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="/docs/">Alt</a>
</li>
<li>
<a href="/docs/createActions">Creating Actions</a>
</li>
<li>
<a href="/docs/actions">Actions</a>
</li>
<li>
<a href="/docs/createStore">Creating Stores</a>
</li>
<li>
<a href="/docs/stores">Stores</a>
</li>
<li>
<a href="/docs/async">Handling Async</a>
</li>
<li>
<a href="/docs/lifecycleListeners">Lifecycle Listeners</a>
</li>
<li>
<a href="/docs/bootstrap">Bootstrap</a>
</li>
<li>
<a href="/docs/takeSnapshot">Take Snapshot</a>
</li>
<li>
<a href="/docs/flush">Flush</a>
</li>
<li>
<a href="/docs/recycle">Recycle</a>
</li>
<li>
<a href="/docs/rollback">Rollback</a>
</li>
<li>
<a href="/docs/altInstances">Alt Instances</a>
</li>
<li>
<a href="/docs/components/altContainer">AltContainer</a>
</li>
</ul>
</li>
<li>
<a href="/blog/">Blog</a>
</li>
<li>
<a href="https://gitter.im/goatslacker/alt">Support</a>
</li>
<li>
<a href="https://github.com/goatslacker/alt">GitHub</a>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="main sp-vert-md sp-horiz-lg">
<div class="row">
<div class="col c2">
<ul class="sidenav">
<li>
<a href="/guide/">Getting Started</a>
</li>
<li>
<a href="/guide/actions/">Creating Actions</a>
</li>
<li>
<a href="/guide/store/">Creating a Store</a>
</li>
<li>
<a href="/guide/view/">Using your View</a>
</li>
<li>
<a href="/guide/async/">Fetching Data</a>
</li>
<li>
<a href="/guide/wait-for/">Data Dependencies</a>
</li>
<li>
<a href="/guide/container-components">Container Components</a>
</li>
<li>
<a href="/guides/es5/">Using Alt with ES5</a>
</li>
</ul>
</div>
<div class="col c10">
<div class="sp-horiz-md">
<h1 id="fetching-data">Fetching Data</h1>
<p>The age old debate, where should async go? There is no right answer right now and don’t feel bad if you’re putting it in actions or in stores. In this tutorial, we’ll be calling async from the actions and the data fetching will exist in a new folder <code>utils</code>. This tutorial will handle fetching the data and failure states.</p>
<p>So we create <code>utils/LocationsFetcher.js</code>. We can use something like <a href="https://github.com/github/fetch">fetch</a> to fetch some data from a server, but for the purposes of this tutorial we’ll just simulate an XHR with good ol’ <code>setTimeout</code> and <code>Promise</code> so we copy fetch’s API.</p>
<p>Here’s some mock data we’ll be using</p>
<pre><code class="language-js">var mockData = [
{ id: 0, name: 'Abu Dhabi' },
{ id: 1, name: 'Berlin' },
{ id: 2, name: 'Bogota' },
{ id: 3, name: 'Buenos Aires' },
{ id: 4, name: 'Cairo' },
{ id: 5, name: 'Chicago' },
{ id: 6, name: 'Lima' },
{ id: 7, name: 'London' },
{ id: 8, name: 'Miami' },
{ id: 9, name: 'Moscow' },
{ id: 10, name: 'Mumbai' },
{ id: 11, name: 'Paris' },
{ id: 12, name: 'San Francisco' }
];
</code></pre>
<p>So let’s create the LocationsFetcher.</p>
<p><code>utils/LocationsFetcher.js</code></p>
<pre><code class="language-js">var LocationsFetcher = {
fetch: function () {
// returning a Promise because that is what fetch does.
return new Promise(function (resolve, reject) {
// simulate an asynchronous action where data is fetched on
// a remote server somewhere.
setTimeout(function () {
// resolve with some mock data
resolve(mockData);
}, 250);
});
}
};
</code></pre>
<p>Next, we’ll need to change the actions to use this new method we created. We will add an action called <code>fetchLocations</code> which will fetch the locations and then call <code>updateLocations</code> when it successfully completes. A new action is also added, <code>locationsFailed</code> which deals with the locations not being available. Add these methods to the class.</p>
<p><code>actions/LocationActions.js</code></p>
<pre><code class="language-js">fetchLocations() {
// we dispatch an event here so we can have "loading" state.
this.dispatch();
LocationsFetcher.fetch()
.then((locations) =&gt; {
// we can access other actions within our action through `this.actions`
this.actions.updateLocations(locations);
})
.catch((errorMessage) =&gt; {
this.actions.locationsFailed(errorMessage);
});
}
locationsFailed(errorMessage) {
this.dispatch(errorMessage);
}
</code></pre>
<p>Next we’ll update our store to handle these new actions. It’s just a matter of adding the new actions and their handlers to <code>bindListeners</code>. We’ll be adding a new piece of state though, ‘errorMessage’ to deal with any potential error messages.</p>
<p><code>stores/LocationStore.js</code></p>
<pre><code class="language-js">class LocationStore {
constructor() {
this.locations = [];
this.errorMessage = null;
this.bindListeners({
handleUpdateLocations: LocationActions.UPDATE_LOCATIONS,
handleFetchLocations: LocationActions.FETCH_LOCATIONS,
handleLocationsFailed: LocationActions.LOCATIONS_FAILED
});
}
handleUpdateLocations(locations) {
this.locations = locations;
this.errorMessage = null;
}
handleFetchLocations() {
// reset the array while we're fetching new locations so React can
// be smart and render a spinner for us since the data is empty.
this.locations = [];
}
handleLocationsFailed(errorMessage) {
this.errorMessage = errorMessage;
}
}
</code></pre>
<p>And finally, the view will change slightly. We’ll be displaying an error message if it exists and showing a spinner if the content is loading.</p>
<pre><code class="language-js">componentDidMount() {
LocationStore.listen(this.onChange);
LocationActions.fetchLocations();
},
render() {
if (this.state.errorMessage) {
return (
&lt;div&gt;Something is wrong&lt;/div&gt;
);
}
if (!this.state.locations.length) {
return (
&lt;div&gt;
&lt;img src="/my-cool-spinner.gif" /&gt;
&lt;/div&gt;
)
}
return (
&lt;ul&gt;
{this.state.locations.map((location) =&gt; {
return (
&lt;li&gt;{location.name}&lt;/li&gt;
);
})}
&lt;/ul&gt;
);
}
</code></pre>
<p><a href="/guide/wait-for">Continue to next step…</a></p>
</div>
</div>
</div>
</div>
<script type="application/javascript" src="http://alt.js.org/assets/search.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/prism/0.0.1/prism.min.js"></script>
<script type="text/javascript">
// Alias for javascript so syntax highlighting works fine
Prism.languages.js = Prism.languages.javascript;
</script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js" ></script>
<script type="text/javascript" src="/assets/bootstrap-navbar.min.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment