Last active
August 29, 2015 14:17
-
-
Save mattmccray/1d511ba1ee3affd01b7e to your computer and use it in GitHub Desktop.
Revisions
-
mattmccray revised this gist
Mar 18, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -94,7 +94,7 @@ In the application, I treat `undefined` and `null` differently. If a value is `u --- Just for completeness, here's the implementation of my `FetchStore`. It's not plug-n-play because I have a class (`Resource`) that wraps the CRUD url generation and xhr calling. But it'd be easy to hook up with raw xhr calls. ```javascript import alt from './alt' -
mattmccray revised this gist
Mar 18, 2015 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -122,7 +122,7 @@ class FetchStore { enqueued= this.queue[ token], api= Resource.type( type) if( enqueued) { // Request already sent... if( callback) { // Add this callback to the other queued callbacks @@ -145,7 +145,7 @@ class FetchStore { FetchActions.resourceFetched({ type, query, token, data}) } else { FetchActions.resourceFetchFailure({ type, query, token, data}) } info.callbacks -
mattmccray revised this gist
Mar 18, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -94,7 +94,7 @@ In the application, I treat `undefined` and `null` differently. If a value is `u --- Just for completeness, here's the implementation my `FetchStore`. It's not plug-n-play because I have a class (`Resource`) that wraps the CRUD url generation and xhr calling. But it'd be easy to hook up with raw xhr calls. ```javascript import alt from './alt' -
mattmccray revised this gist
Mar 18, 2015 . 1 changed file with 83 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,7 +29,7 @@ class FetchActions { } // Primarily used in resolving data pre-route rendering, // this returns a Promise that resolves once the resource(s) // have been loaded and processed through the dispatcher. retrieveResource( type, query) { return new Promise(( resolve, reject) => { @@ -91,3 +91,85 @@ export default alt.createStore( CompanyStore, 'CompanyStore') ``` In the application, I treat `undefined` and `null` differently. If a value is `undefined` it's unfetched data, if `null` then it's been fetched with no results --- Just for completeness, here's my implementation my `FetchStore`. It's not plug-n-play because I have a class (`Resource`) that wraps the CRUD url generation and xhr calling. But it'd be easy to hook up with raw xhr calls. ```javascript import alt from './alt' import FetchActions from './FetchActions' import {Resource} from 'toolkit' class FetchStore { constructor() { this.bindActions( FetchActions) this.queue= {} } onLoadResource({ type, query }) { this._loadResource( type, query) } onRetrieveResource({ type, query, callback }) { this._loadResource( type, query, callback) } _loadResource( type, query, callback) { const token= this._tokenize( type, query), enqueued= this.queue[ token], api= Resource.type( type) if( enqueued ) { // Request already sent... if( callback) { // Add this callback to the other queued callbacks enqueued.callbacks.push( callback) } return } this.queue[ token]= defaultState() const apiCall= (Type.isObject( query) ? api.find( query) : api.get( query)) .then( this._resourceResponse.bind( this, type, query, token, true)) .catch( this._resourceResponse.bind( this, type, query, token, false)) } _resourceResponse( type, query, token, success, data) { const info= this.queue[ token] if( success) { FetchActions.resourceFetched({ type, query, token, data}) } else { FetchActions.resourcenUnfetched({ type, query, token, data}) } info.callbacks .forEach( callback => { if( success) callback( null, data) else callback( data) }) delete this.queue[ token] } _tokenize( type, query) { return JSON.stringify({ type, query}) } } export default alt.createStore( FetchStore, 'FetchStore') function defaultState() { return { callbacks: [], error: null, finish: null, start: new Date() } } ``` -
mattmccray created this gist
Mar 17, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ # Async Data Fetching Consider it a given that this talks to a RESTful API (simple crud and, in my case, predicate filtering). There is a `FetchStore` that manages the API calls, ensuring there aren't duplicate calls, resolving promises once data arrives, etc. The store itself is rather opaque. It doesn't have any public accessors. The `FetchActions` defines two actions for clients to call, and two for other stores to consume in the dispatch cycle: ```javascript import alt from './alt' class FetchActions { constructor() { this.generateActions( // Stores listen for this, payload contains resource type, // query, and response data. 'resourceFetched', // Same, except contains error information 'resourceFetchFailure' ) } // A 'fire and forget' method used by other stores. Just // signals that data needs to be fetched for this type // and query (usually an id). loadResource( type, query) { this.dispatch({ type, query }) } // Primarily used in resolving data pre-route rendering, // this returns a Promise that resolves once the resource // have been loaded and processed through the dispatcher. retrieveResource( type, query) { return new Promise(( resolve, reject) => { function callback( err, data) { if( err) reject( err) else resolve( data) } this.dispatch({ type, query, callback }) }) } } export default alt.createActions( FetchActions) ``` That's basically it. Internally, the `FetchStore` keeps track of pending requests, and any associated callbacks, resolving them once the `xhr` returns. Here's an example of how it's used by other Stores: ```javascript import alt from './alt' import CompanyActions from './CompanyActions' import FetchActions from './FetchActions' const COMPANY_TYPE= "Company" class CompanyStore { constructor() { this.bindActions( CompanyActions) this.bindActions( FetchActions) this.idmap= {} } onResourceFetched({ type, query, data }) { if( type === COMPANY_TYPE) { this.idmap[ data.companyId]= data } else { return false } } static get( id) { const company= this.getState().idmap[ id] if( Type.isUndefined( company)) { FetchActions.loadResource( COMPANY_TYPE, id) } return company } } export default alt.createStore( CompanyStore, 'CompanyStore') ``` In the application, I treat `undefined` and `null` differently. If a value is `undefined` it's unfetched data, if `null` then it's been fetched with no results