hyrest-mobx
v0.2.4
Published
A hybrid REST library for the frontend and backend. MobX connector package.
Downloads
1
Maintainers
Readme
hyrest-mobx
Hyrest is a hybrid REST framework for both the client and the server.
This is the MobX frontend utility package.
After creating and exposing a REST API using hyrest and hyrest-express it might be useful to re-use the existing models and validation from the server side in the client to store data next to forms and perform validation on it.
Usage
Fields
Let's say a model has been defined which is already used by a controller:
import { is, email, length } from "hyrest";
class User {
@is().validate(email) public email: string;
@is().validate(length(5, 20)) public name: string;
@is().validate(length({ min: 10 })) public password: string;
}
In order to create a new user, one might want to implement a sign up form. This is where this package can come in handy.
Instead of creating a @observable public email: string
and so on for each field on the User
model, simple utilize hyrest-mobx:
import * as React from "react";
import { observer } from "mobx-react";
import { field, hasFields, Field } from "hyrest-mobx";
@observer @hasFields()
class Signup extends React.Component {
@field(User) private user: Field<User>;
@action.bound private handleSubmit() {
console.log(user.value); // Will log the unwrapped user.
}
public render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" {...this.user.nested.email.reactInput} />
<input type="text" {...this.user.nested.name.reactInput} />
<input type="password" {...this.user.nested.password.reactInput} />
{
this.users.errors.map((err, index) => <p key={index}>{err}</p>)
}
<button disabled={!this.user.valid}>Signup</button>
</form>
);
}
}
The decorator @field
will mark the property as a field with the type User
.
After marking the class with @hasFields
, new Field
s will automatically be injected upon creation.
The injected values already utilize Mobx under the hood and hence no @observable
s are no longer necessary.
Store
A utility for generating stores from controllers exists.
Let's say you implemented a controller with search
, get
and create
methods:
class Model {
id?: string;
name?: string;
}
class DemoController {
public async create(model: Model) {
...
}
public async search(name: string, id?: string) {
...
}
public async get(id: string) {
...
}
}
It is then possible to generate similar actions on the store's base class.
These methods will keep the internal entities
map in sync and perform the corresponding operations on the controller:
class DemoStore extends Store(DemoController) {
protected controller = new DemoController();
}
// `DemoStore.create` exists.
// `DemoStore.get` exists.
// `DemoStore.getLazy` exists.
// `DemoStore.search` exists.