Skip to content

Model

Model is a front-end class representation of a server resource. Its fields (especially properties) should resemble the incoming resource's structure as close as possible.

The following is an example of Model definition.

typescript
import { Model } from '@kovalson/prevue';

class User extends Model {
  readonly id: string = '';
  readonly firstName: string | null = null;
  readonly lastName: string | null = null;
  readonly email: string = '';
}

export {
  User,
};

Configuration

Primary Key

Model's $primaryKey static attribute defines which of its properties is a primary key. The primary key is used to uniquely distinguish objects. In most cases, such key would be id which is also a default value for all models. If your model uses other property as a primary key, you may overwrite this static property to reflect that.

typescript
import { Model } from '@kovalson/prevue';

class AuthUser extends Model {
  public static $primaryKey = 'token';

  readonly token: string = '';
  readonly email: string = '';
}

Note that the primary key is used by the repository and API composables, so it's mandatory to set it correctly.

Converting Properties Case

The $convertCase protected property, when set to true, enables transforming all other-cased properties keys into camelCase.

For example, if your model uses camelCase properties:

typescript
class User extends Model {
  readonly emailAddress: string = '';
  readonly lastLoggedIn: string | null = null;
}

but the server returns data in any other case (even if the casing is mixed):

json
{
  "email_address": "example@user.test",
  "Last Logged In": "1970-01-01T00:00:00.000Z"
}

you can simply set the $convertCase to true:

typescript
class User extends Model {
  readonly emailAddress: string = '';
  readonly lastLoggedIn: string | null = null;
  
  protected $convertCase = true;
}

This way all received data properties will be converted into camelCase before assigning.

Relations

The $relations protected property stores an object that defines a map describing which property holds a relation to other model. This is required for nested data to be properly converted into Prevue models. For example:

typescript
import { Model } from '@kovalson/prevue';
import { Comment } from '~/models/Comment';

class User extends Model {
  readonly id: string = '';
  readonly comments: Comment[] = [];
  
  protected $relations = {
    comments: Comment,
  };
}
typescript
import { Model } from '@kovalson/prevue';
import { User } from '~/models/User';

class User extends Model {
  readonly id: string = '';
  readonly content: string = '';
  readonly owner: User = new User();
  
  protected $relations = {
    owner: User,
  };
}

WARNING

Note that, as mentioned in the introduction, this is not an ORM. There are no advanced relations such as belongsTo() or hasMany(). There are also no joins, and there's no eager loading. The relations serve much simpler purpose, only to convert incoming data into corresponding models.

Creating Models

If you want to create a model instance with predefined values, you may use the following simplified utility function:

typescript
import { Model, createInstance } from '@kovalson/prevue';

class User extends Model {
  readonly id: string = '';
  readonly firstName: string | null = null;
  readonly lastName: string | null = null;
  readonly email: string = '';
}

const user = createInstance(User, {
  id: 'some-id',
  firstName: 'User',
});

This method takes the model constructor as a first parameter. The second, optional parameter is a partial data object that extends the given model. This data object allows any property since its word casing may be further converted, but thanks to extending the original model IDEs should have no problem hinting correct keys.

Internal Functionality

The $update() method

This public method is used by internal functions to update models (you can learn more about it here). Though it's public and available in every model, it should never be overridden unless you know exactly what you are doing.

This method creates a new instance of model with updated properties passed as an argument.

typescript
import { Model } from '@kovalson/prevue';

class User extends Model {
  readonly id: string = '';
  readonly firstName: string | null = null;
  readonly lastName: string | null = null;
  readonly email: string = '';
}

// ...

const user = new User();
const updatedUser = user.$update({
  firstName: 'Example',
  lastName: 'User',
});

Note that instantiating a model, and using the $update() method afterward is the same as using the createInstance() utility mentioned before.

TIP

If your model has the $convertCase property set to true, the keys of the passed object may use different word case.

Released under the MIT License.