Skip to content

Instantly share code, notes, and snippets.

@100ideas
Forked from faiyaz26/mobx_store.ts
Created October 18, 2019 05:59
Show Gist options
  • Save 100ideas/7f62538c8240190f5bf21e4028d338fe to your computer and use it in GitHub Desktop.
Save 100ideas/7f62538c8240190f5bf21e4028d338fe to your computer and use it in GitHub Desktop.
MobX depedency tree
import {action, computed, observable, runInAction} from 'mobx';
import Loadable from './loadable';
export default class Loadable<T> {
// our state entity class
public static create<T>(val?: T) {
return new Loadable<T>(val);
}
@observable private value: T;
@observable private loading: boolean = false;
constructor(val?: T) {
this.set(val);
}
public isLoading() {
return this.loading;
}
public val() {
return this.value;
}
public set(value: T) {
this.loading = false;
this.value = value;
}
public setLoading(loading: boolean) {
this.loading = loading;
}
}
interface IProject {
projectName: string;
projectId: string;
}
export class RootStore {
@observable public currentProjectId: string = null;
@observable public projectsList = Loadable.create<IProject[]>();
public readonly projectStoreMap = new Map<string, ProjectStore>();
public projectStore(projectId: string) {
if (!this.projectStoreMap.has(projectId)) {
const project = this.projectsList
.val()
.find(project => project.projectId === projectId);
if (!project) {
throw new Error('Project not found');
}
this.projectStoreMap.set(projectId, new ProjectStore(project));
}
return this.projectStoreMap.get(projectId);
}
@computed public get currentProjectStore() {
return this.projectStore(this.currentProjectId);
}
@action public setCurrentProjectId(projectId: string) {
this.currentProjectId = projectId;
}
@action.bound
public async fetchProjectsList() {
this.projectsList.setLoading(true);
const response = await ApiService.get().projectList({});
runInAction('fetchProjectsListSuccess', () =>
this.projectsList.set(response.projects)
);
}
}
interface IBranch {
branchName: string;
}
class ProjectStore {
public readonly currentProject: IProject;
@observable public branchList = Loadable.create<IBranch[]>();
@observable public currentBranchName: string = null;
public readonly branchStoreMap = new Map<string, BranchStore>();
constructor(project: IProject) {
this.currentProject = project;
}
public branchStore(branchName: string) {
if (!this.branchStoreMap.has(branchName)) {
const branch = this.branchList
.val()
.find(branch => branch.branchName === branchName);
if (!branch) {
throw new Error('Branch not found');
}
this.branchStoreMap.set(branchName, new BranchStore(branch));
}
return this.branchStoreMap.get(branchName);
}
@computed public get currentBranchStore() {
return this.branchStore(this.currentBranchName);
}
@action public setCurrentBranchName(branchName: string) {
this.currentBranchName = branchName;
}
@action.bound
public async fetchBranchList() {
this.branchList.setLoading(true);
const response = await ApiService.get().branchList({
projectId: this.currentProject.projectId,
});
runInAction('fetchBranchListSuccess', () =>
this.branchList.set(response.branches)
);
}
}
const rootStore = new RootStore();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment