2017-01-27 03:10:28 +03:00
# Writing a model
This is a documentation to help create models which are DataStructure that maps entities returned by apis.
2018-03-03 01:43:53 +03:00
All models should be immmutable using the record api defined in `@batch-flask/core` .
2017-01-27 03:10:28 +03:00
2017-05-11 00:41:32 +03:00
Note: Before writting a model double check this is the best option:
2021-03-06 18:13:46 +03:00
2017-05-11 00:41:32 +03:00
* Models should be for containg data returned from remote APIs.
* Models are immutable which means it should not be for a structure containing user edit.
* Don't use models for internal data structure.(For a component or a small set of components)
2017-01-27 03:10:28 +03:00
2021-03-06 18:13:46 +03:00
## Step 1: Create file
2017-02-08 02:13:12 +03:00
Create model file `my-new-model.ts` in `app/models`
2017-01-27 03:10:28 +03:00
add this to `app/models/index.ts`
```typescript
2017-05-11 00:41:32 +03:00
export * from "./my-model"
2017-01-27 03:10:28 +03:00
```
Then you should be able to have
```typescript
// Good
import { MyNewModel } from "app/models"
// Bad
2017-05-11 00:41:32 +03:00
import { MyNewModel } from "app/models/myNewModel"
2017-01-27 03:10:28 +03:00
```
2021-03-06 18:13:46 +03:00
## Step 2: Write the attribute interface
2017-02-09 01:18:26 +03:00
In this interface define all the attributes of the model
This may look like we are creating a lot of duplicate code here but it makes it worth it when using the model later as you'll have typing when creating a new model.
```typescript
import { Partial } from "app/utils"
export interface MyModelAttributes {
id: string;
state: string;
2017-05-11 00:41:32 +03:00
files: Partial< BarAttributes > [];
2017-02-09 01:18:26 +03:00
bar: Partial< BarAttributes >
}
```
2017-05-11 00:41:32 +03:00
### Step 3: Write the model class
2017-01-27 03:10:28 +03:00
2017-05-11 00:41:32 +03:00
You need to do the following for the class:
2021-03-06 18:13:46 +03:00
* Decorate the class with the `@Model` decorator
* Extend the class with the `Record` class
* Decorate all attributes of the model with `@Prop` and all list attributes with `@ListProp` . Note: `@Prop` will be able to get the type of a nested model automatically. However you need to pass the type of the model in the list decorator.
* For default values just set the value in the class body `@Prop public a: string = "abc"`
2017-01-27 03:10:28 +03:00
```typescript
2018-03-03 01:43:53 +03:00
import { ListProp, Model, Prop, Record } from "@batch-flask/core";
2017-02-09 01:18:26 +03:00
import { Bar, BarAttributes } from "./bar"
2017-05-11 00:41:32 +03:00
@Model ()
export class MyModel extends Record< MyModelAttributes > {
@Prop ()
public id: string = "default-value";
@Prop ()
2017-01-27 03:10:28 +03:00
public state: string;
2017-05-11 00:41:32 +03:00
@Prop ()
2017-01-27 03:10:28 +03:00
public bar: Bar;
2017-02-09 01:18:26 +03:00
2017-05-11 00:41:32 +03:00
@ListProp (Bar)
public files: List< Bar > ;
2017-01-27 03:10:28 +03:00
}
```
2017-05-11 00:41:32 +03:00
The record api will make all attributes with `@Prop` immutable. If you have a nested object it will automatically create it. And when using `@ListProp` it will automatically create a immutable list of items.