Last active
September 1, 2015 00:48
-
-
Save goatslacker/b3ea014881aa5b03488d to your computer and use it in GitHub Desktop.
This file contains 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 characters
export default function fetch(store, source) { | |
const storeInst = store.getInstance ? store.getInstance() : store | |
const state = storeInst.getState() | |
const validHandlers = ['success', 'failure', 'begin', 'end'] | |
validHandlers.forEach((handler) => { | |
if (source[handler] && !source[handler].id) { | |
throw new Error(`${handler} handler must be an action function`) | |
} | |
}) | |
const value = source.local && source.local(state) | |
const shouldFetch = source.shouldFetch | |
? source.shouldFetch(state) | |
: value == null | |
if (shouldFetch) { | |
if (source.begin) source.begin() | |
const result = source.remote(state) | |
result.then(source.success, source.failure).then(source.end) | |
return result | |
} else { | |
return Promise.resolve(value) | |
} | |
} |
This file contains 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 characters
// or you can just export the source and attach it wherever | |
import CompanyActions from '../actions/CompanyActions' | |
import { fetchCompanyUsingXhr } from '../request' | |
export default { | |
// required | |
local: state => state.company, | |
// optional | |
shouldFetch: state => !state.company || state.company._id !== state.companyId, | |
// required | |
remote: state => fetchCompanyUsingXhr(state.companyId), | |
// optional | |
begin: CompanyActions.fetchingCompany, | |
// required | |
success: CompanyActions.companyRetrieved, | |
// required | |
failure: CompanyActions.companyRequestFailed, | |
// optional | |
end: CompanyActions.fetchedCompany, | |
}) | |
} |
This file contains 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 characters
// using it in a store, you don't have to! | |
import alt from '../alt' | |
import CompanyActions from '../actions/CompanyActions' | |
import { fetchCompanyUsingXhr } from '../request' | |
import fetch from '../fetch' | |
class CompanyStore { | |
static displayName = 'CompanyStore' | |
constructor() { | |
this.exportPublicMethods({ | |
fetchCompany: this::this.fetchCompany, | |
getCompanyId: this::this.getCompanyId, | |
}) | |
this.bindActions(CompanyActions) | |
this.state = { | |
companyId: 1, | |
company: null, | |
} | |
} | |
companyRetrieved(company) { | |
this.setState({ | |
company, | |
companyId: company._id, | |
}) | |
} | |
getCompanyId() { | |
return this.state.companyId | |
} | |
fetchCompany() { | |
return fetch(this, { | |
// required | |
local: state => state.company, | |
// optional | |
shouldFetch: state => !state.company || state.company._id !== state.companyId, | |
// required | |
remote: state => fetchCompanyUsingXhr(state.companyId), | |
// optional | |
begin: CompanyActions.fetchingCompany, | |
// required | |
success: CompanyActions.companyRetrieved, | |
// required | |
failure: CompanyActions.companyRequestFailed, | |
// optional | |
end: CompanyActions.fetchedCompany, | |
}) | |
} | |
} | |
export default alt.createStore(CompanyStore) |
This file contains 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 characters
// you can use it as part of a util method | |
import fetch from '../fetch' | |
import CompanyStore from '../stores/CompanyStore' | |
import FetchCompanySource frmo '../sources/FetchCompanySource' | |
export const fetchCompany = () => fetch(CompanyStore, FetchCompanySource) |
Is the biggest difference between this and the current Alt data source that it's more decoupled from the store itself? Pretty nice if so.
Two things that might be worth considering -
- Assigning something like an ID to a fetch operation so that multiple "identical" concurrent fetches can be deduped
- Some sort of unification of fetch with containers/&c. such that it's easy to use the fetch's return value for rendering a component (instead of separately specifying "fetch data" and "read data from store"... the resolved promise with the local value gets you most of the way there I guess)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cc @lelandrichardson @taion