A tiny library that makes working with promises in MobX easy.
npm install --save mobx-promise
Simply initialize an observable object with data
and promiseState
properties, and return a promise from an action decorated with @bindPromiseTo
as such:
import { bindPromiseTo } from 'mobx-promise'
class FoodStore {
@observable pizzas = {
data: {},
promiseState: {},
}
@bindPromiseTo('pizzas')
@action getPizzas() {
return fetch('pizza-store.com/api/get')
}
}
Now when getPizzas()
is called, mobx-promise
will update the promiseState
property of pizzas
with promise's lifecycle events — pending, fulfilled or rejected, and the data
property with the result of promise execution.
If you'd like more control on how the promise results are assigned, or if you wish to avoid using decorators, you can use the bindPromise
function instead of the @bindPromiseTo
decorator.
import { bindPromise } from 'mobx-promise'
@action getPizzas() {
const pizzaPromise = fetch('pizza-store.com/api/get').then(r => r.json())
bindPromise(pizzaPromise)
.to(this.pizzas)
}
This works similar to bindPromiseTo
, but allows you more freedom to do any of the following:
@action getPizzas() {
const pizzaPromise = fetch('pizza-store.com/api/get').then(r => r.json())
bindPromise(pizzaPromise)
.to(this.pizzas, (promiseResult) => promiseResult.data.pizzas)
}
@action getMorePizzas() {
const pizzaPromise = fetch('pizza-store.com/api/get').then(r => r.json())
// Merge / process current result with the previous one
bindPromise(pizzaPromise)
.to(this.pizzas, (newResults, oldPizzas) => oldPizzas.concat(newResults))
}
@action getMorePizzas() {
const pizzaPromise = fetch('pizza-store.com/api/get').then(r => r.json())
return bindPromise(pizzaPromise)
.to(this.pizzas)
}
@action getMorePizzas() {
const pizzaPromise = fetch('pizza-store.com/api/get').then(r => r.json())
bindPromise(pizzaPromise)
.to(this.pizzas)
.then((result) => console.log(result))
.catch((err) => alert(err))
}
mobx-promise
provides the PromiseState
enum for convenience in comparing results. You can choose to use "fulfilled", "rejected" and "pending" as strings instead if you wish.
import { Component } from 'react'
import { PromiseState } from 'mobx-promise'
class PizzaApp extends Component {
render() {
const { pizzas } = appStore
switch(pizzas.promiseState) {
case PromiseState.PENDING:
return <span> Loading yummy pizzas... </span>
case PromiseState.FULFILLED:
return <ul> { pizzas.data.map(pizzaName => <li> { pizzaName } </li>) } </ul>
case PromiseState.REJECTED:
return <span> No pizza for you. </span>
}
}
}
|argument|type| |--------|----|-------| |promise |Promise|
argument | type |
---|---|
observable | MobX Observable |
selector(newData, oldData) | callback |
argument | type |
---|---|
observableKey | string |