Skip to content

ServiceInstance API

Learn about instance-level properties and methods on service-related data.

Instance API Overview

Every record retrieved from the API or service store will be a functional ServiceInstance with the following instance API. You can also manually create instances using the service.new method.

ts
api.service('todos').new(data)

Every instance contains the properties described below.

Built on the Data Stores Instance API

All FeathersModel instances also include the properties and methods found in the StoreInstance API. This page only covers the methods that are unique to FeathersModel instances.

Instance Properties

__isServiceInstance

A boolean that indicates that this is a Feathers instance.

isPending

Reads store state and evaluates to true if any type of request is pending for the instance.

ts
import { Task } from '../models/task'

const task = Task({ description: 'Do the dishes' })
const request = task.save() // or any Feathers method
console.log(task.isPending) // --> true

isSavePending

Reads store state and evaluates to true if there is a pending create or patch request for the instance.

ts
task.isSavePending // --> boolean

isCreatePending

Reads store state and evaluates to true if there is a pending create request for the instance.

ts
task.isCreatePending // --> boolean

isPatchPending

Reads store state and evaluates to true if there is a pending patch request for the instance.

ts
task.isPatchPending // --> boolean

isRemovePending

Reads store state and evaluates to true if there is a pending removerequest for the instance.

ts
task.isRemovePending // --> boolean

API Methods

The following methods are available on FeathersModel instances:

instance.save(params)

The save method is a convenience wrapper for the create/patch methods. If the record has no idField, the instance.create()method will be used. Theparams argument will be used in the Feathers client request. See the Feathers Service docs, for reference on where params are used in each method.

ts
import { Task } from '../models/task'

// Call createInStore to get a reactive Vue object
const task = Task({ description: 'Do something!' }).createInStore()

await task.save() // --> Creates the task on the server.

Once the create response returns, the record will have an idField assigned by the server. Most databases give each record an id. Others use a different field. For example, MongoDB uses _id. If you call instance.save() again, the method will call instance.patch(). Which method is used depends solely on whether the data has a proeprty matchin ghte idField in the service store.

When calling save() on a clone, you can use special params to handle patch diffing.

instance.create(params)

The create method calls the create action (service method) using the instance data. The params argument will be used in the Feathers client request. See the Feathers Service docs, for reference.

You might not ever need to use .create(), but can instead use the .save() method. Let Feathers-Pinia call create or patch.

js
const task = Task({ description: 'Do something!' })

await task.create() // --> Creates the task on the server using the instance data

instance.patch(data, params)

The patch method calls the patch action (service method) using the instance data. The instance's id field is used for the patch id. The params argument will be used in the Feathers client request. See the Feathers Service docs, for reference.

Similar to the .create() method, you might not ever need to use .patch() if you just use .save() and let Feathers-Pinia figure out how to handle it.

js
const task = Task({ id: 1, description: 'Do something!' })
task.description = 'Do something else'
await task.patch() // --> Sends a `patch` request the with the id and description.

When calling save() on a clone, you can use special params to handle patch diffing.

instance.remove(params)

Patch Diffing

Efficiency Tip

Don't waste bandwidth! Just send the props that change!

Patch diffing, which originated in Feathers-Vuex, is now back in Feathers-Pinia with a smarter, faster algorithm that will work for any scenario you can dream up.

Diffing only occurs on patch requests (and when calling instance.save() calls a patch).

ts
// clone a record
const clone = user.clone()
// make changes
clone.name = 'Feathers is Amazing!'
// save
await clone.save() // --> Only the changed props go to the server!

How It Works

  • By default, all keys are deep-compared between the original record and the clone.
  • Once all changes are found, only the top-level keys are sent to the server.

Diffing will work on all databases without data loss.

Customize the Diff

You can use the diff option to customize which values are compared. Only props that have changed will be sent to the server.

ts
// string: diff only this prop
await clone.save({ diff: 'teamId' })

// array: diff only these props
await clone.save({ diff: ['teamId', 'username'] })

// object: merge and diff these props
await clone.save({ diff: { teamId: 1, username: 'foo' } })

// or turn off diffing and send everything
await clone.save({ diff: false })

Always Save Certain Props

If there are certain props that need to always go with the request, use the with option:

ts
// string: always include this prop
await clone.save({ with: 'teamId' })

// array: always include these props
await clone.save({ with: ['teamId', 'username'] })

// object: merge and include these props
await clone.save({ with: { teamId: 1, username: 'foo' } })

Specify Patch Data

When calling .save() or .patch(), you can provide an object as params.data, and Feathers-Pinia will use it as the patch data. This bypasses the diff and with params.

js
const { api } = useFeathers()

const task = api.service('tasks').new({ description: 'Do Something', isComplete: false })
await task.patch({ data: { isComplete: true } })

Eager Commits

Eager updates are enabled, by default, when calling patch/save on a clone. This means that commit is called before the API request goes out. If an API errors occurs, the change will be rolled back.

Sometimes eager commits aren't desirable, so you can turn them off when needed by passing { eager: false }, like this:

ts
await clone.save({ eager: false })

With eager: false, the commit will happen after the API server responds to the patch request.

Many thanks go to the Vue and FeathersJS communities for keeping software development FUN!