Skip to content

Instantly share code, notes, and snippets.

@fabiosussetto
Created May 17, 2017 17:37
Show Gist options
  • Save fabiosussetto/7013e13cfa1ea7fd83cce57787d21ee5 to your computer and use it in GitHub Desktop.
Save fabiosussetto/7013e13cfa1ea7fd83cce57787d21ee5 to your computer and use it in GitHub Desktop.
import { when, reaction } from "mobx";
import { types, getParent, getRoot, getSnapshot, applySnapshot } from "mobx-state-tree";
import uuid from 'uuid/v4'
import request from '../api'
const AuthStore = types.model(
'AuthStore',
{
token: '',
isLoading: false
},
{
afterCreate() {
when(
() => !this.isLoading,
() => {
this.readFromLocalStorage();
reaction(
() => getSnapshot(this),
json => {
// window.localStorage.setItem('cart', JSON.stringify(json));
}
)
}
)
},
readFromLocalStorage() {
const localData = JSON.parse(window.localStorage.getItem('reduxPersist:auth') || {})
applySnapshot(this, { token: localData.token })
}
}
);
const ApiStore = types.model(
'ApiStore',
{
baseUrl: 'http://localhost:8000/api',
},
{
call (method, url, config={}) {
const token = getRoot(this).auth.token
return request({
method,
url: `${this.baseUrl}${url}`,
headers: token ? { Authorization: `Token ${token}` } : {},
...config
})
}
}
);
const User = types.model('User', {
id: types.identifier(),
username: types.string,
email: types.string,
});
const Users = types.model(
'Users',
{
entries: types.map(User)
},
{
insertUserFromJson(user) {
return this.entries.put(user)
},
}
);
const Comment = types.model('Comment', {
id: types.identifier(),
createdBy: types.reference(User, '/users'),
content: types.string,
createdAt: types.string
});
const Comments = types.model(
'Comments',
{
entries: types.map(Comment),
get apiStore () {
return getRoot(this).api
},
get userStore () {
return getRoot(this).users
}
},
{
fetchEventComments (eventId) {
this.apiStore.call('get', `/comments/`)
.then(comments => {
// comments is a json response from the api containing data like:
// [ { id: 'uuid-1', content: 'my test content', ..., createdBy: { id: 1, username: 'fabio', email: '...' } } ]
comments.forEach(comment => {
// need to convert createdBy.id as string as not sure if types.identifier works with integers?
const user = this.userStore.insertUserFromJson({ ...comment.createdBy, id: comment.createdBy.id.toString() })
// now do I store the reference? Do I need to?
this.insertCommentFromJson({ ...comment, createdBy: user.id})
})
})
.catch(error => {
console.error(error)
})
},
insertCommentFromJson(comment) {
this.entries.put(comment)
},
addComment(data) {
const comment = {
id: uuid(),
createdAt: new Date().toISOString(),
...data
}
this.insertCommentFromJson(comment)
this.apiStore.call('post', `/comments/`, { data: comment })
.then(comment => {
this.userStore.insertUserFromJson(comment.createdBy)
this.insertCommentFromJson(comment)
})
.catch(error => {
console.error(error)
})
},
deleteComment(commentId: string) {
this.entries.delete(commentId)
this.apiStore.call('delete', `/comments/${commentId}`)
}
}
);
export const Store = types.model(
'Store',
{
api: types.optional(ApiStore, {}),
users: types.optional(Users, { entries: {} }),
comments: types.optional(Comments, { entries: {} }),
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment