# Notes

Source: https://developers.inkdrop.app/data-access/notes

As the name suggests, notes are a core part of Inkdrop — A note contains an individual note data.

## The note model

The note model contains all the information about your notes, such as their title, content written in Markdown format, associated notebook and tags, creation and modification timestamps, and any other metadata.

### Properties

- **\_id** (string)

  The unique document ID which should start with `note:` and the remains are randomly generated string.
- **\_rev** (string)

  This is a CouchDB specific field. The current MVCC-token/revision of this document (mandatory and immutable).
- **body** (string)

  The content of the note represented with Markdown.
- **bookId** (string)

  The associated notebook ID.
- **createdAt** (number)

  The date time when the note was created, represented with Unix timestamps in milliseconds.
- **doctype** (string)

  The format type of the body field. It currently can take `markdown` only, reserved for the future.
- **migratedBy** (string)

  The type of the data migration.
- **numOfCheckedTasks** (number)

  The number of checked tasks, extracted from body.
- **numOfTasks** (number)

  The number of tasks, extracted from body.
- **pinned** (boolean)

  Whether the note is pinned to top.
- **share** (string)

  The sharing mode of the note. **One of:** `"private"` or `"public"`
- **status** (string)

  The status of the note. **One of:** `"none"` or `"active"` or `"onHold"` or `"completed"` or `"dropped"`
- **tags** (string\[])

  The list of tag IDs.
- **title** (string)

  The note title.
- **updatedAt** (number)

  The date time when the note was last updated, represented with Unix timestamps in milliseconds.

```json title="The note object"
{
  "_id": "note:BkgOZZUJzf",
  "_rev": "38-636e505958d24f9c21614d95ea03b5a1",
  "title": "Hello, world",
  "doctype": "markdown",
  "updatedAt": 1513330812556,
  "createdAt": 1513214207639,
  "tags": [
    "tag:a28ca207"
  ],
  "status": "none",
  "share": "private",
  "body": "markdown note body",
  "bookId": "book:first",
  "numOfTasks": 0,
  "numOfCheckedTasks": 0,
  "pinned": false
}
```

---

## The note class

The `Note` class is a wrapper class that provides methods and functionalities related to handling notes.

### Methods

- **static async loadWithId(noteId: string)**

  A static asynchronous method that retrieves a note from the database using a specified note ID and returns an instance of the `Note` class initialized with that note.
- **constructor(initialValues: Partial\<Note> = {})**

  Constructs a new instance of the `Note` class. It sets the initial values of the note object based on the provided `initialValues` or uses default values.
- **getUpdatedAt()**

  Returns the `updatedAt` property of the note as a JavaScript `Date` object.
- **getCreatedAt()**

  Returns the `createdAt` property of the note as a JavaScript `Date` object.
- **isNoteShared()**

  Determines if the note is shared. Returns `true` if the note is not private; otherwise, it returns `false`.
- **validate()**

  Validates the note's properties using the `validateNote` function. Returns a list of validation errors or an empty list if the note is valid.
- **async save()**

  An asynchronous method that first validates the note, then ensures the related notebook and tags exist. If all validations pass, it saves the note to the database.
- **toObject()**

  Converts the `Note` instance into a plain JavaScript object of type `Note`.
- **toJson()**

  Serializes the `Note` instance into a JSON string representation.

```js title="Import the class"
const { Note } = require('inkdrop').models
```

```js title="Load a note from the database"
const note = await Note.loadWithId('note:BKzzd8iGK')
```

```js title="Change its title"
note.title = 'New title'
```

```js title="Save the change"
await note.save()
```

```js title="Create a new note"
const note = new Note({
  title: 'Hello',
  body: 'World'
})
```

```js title="Convert into a plain object"
const object = note.toObject()
```

```js title="Convert into JSON"
const json = note.toJson()
```

---

## Retrieve a note `get(docId, options)`

Retrieve a note with the given ID.
You can also pass an array of note IDs to retrieve several notes at once.

### Parameters

- **docId** (string | string\[], required)

  The note ID, or an array of note IDs
- **options** (object)

  Options. See [PouchDB's documentation](https://pouchdb.com/api.html#fetch_document) for available options.
  Ignored when `docId` is an array.

### Returns

Returns a note if a valid note ID was provided.
When given an array, returns an array of notes in the same order as the IDs.
IDs of notes that do not exist are omitted instead of throwing an error, but an invalid note ID still throws.

```js
const db = env.localDB
const note = await db.notes.get('note:BKzzd8iGK')
```

```js title="Multiple notes"
const db = env.localDB
const notes = await db.notes.get(['note:BKzzd8iGK', 'note:8eea9f7c'])
```

```json title="Response"
{
  "doctype": "markdown",
  "bookId": "book:tjnPbJakw",
  "createdAt": 1589165355584,
  "updatedAt": 1592532006000,
  "status": "active",
  "share": "private",
  "numOfTasks": 0,
  "numOfCheckedTasks": 0,
  "pinned": true,
  "title": "hello",
  "body": "example note",
  "tags": ["tag:HyBgJ94gx", "tag:h11OMPbSs"],
  "_id": "note:BKzzd8iGK",
  "_rev": "19-d882f96ee27f7b9f71f6183b0cab9193"
}
```

---

## List all notes `all(options)`

Retrieve a list of your notes.

### Parameters

- **options** (object)

  Object with the following keys:
  - **sort** (object\[])

    An array of objects, each indicating a field and order.
    Supported fields are: `'title'`, `'updatedAt'`, `'createdAt'` and `'tagCount'`.
    `'tagCount'` ranks a note by how many of the listed notes share each of its tags, so notes with commonly used tags come first.
    For example: `[ { updatedAt: 'asc' } ]`, `[ { title: 'desc' } ]`.
    Default: `[ { updatedAt: 'desc' } ]`
  - **pinnedFirst** (boolean)

    Whether to list pinned notes first. Default: `true`
  - **limit** (number | false)

    A number to limit how many notes to fetch. Pass `false` to fetch all notes. Default: `50`
  - **skip** (number)

    A number of notes to skip at the start of a collection. Default: `0`
  - **includeDocs** (boolean)

    Whether the result rows include the note documents. When `false`, each row contains only the note's `id` and `rev`. Default: `true`

### Returns

Returns a query result.
The notes are in `rows`, each as `rows[].doc`.
`cursor` is the query for the next page, or `null` if there are no more notes.

```js
const db = env.localDB
const list = await db.notes.all({ limit: 20 })
```

```js title="Response"
{
  query: {
    index: 'notes',
    limit: 20
  },
  totalRows: 9357,
  cursor: {
    index: 'notes',
    limit: 20,
    skip: 20
  },
  includeDocs: true,
  rows: [
    {
      doc: {
        doctype: 'markdown',
        updatedAt: 1461564004766,
        createdAt: 1461563995746,
        bookId: 'book:32b385767dc2',
        status: 'none',
        numOfTasks: 0,
        numOfCheckedTasks: 0,
        title: 'title...',
        body: 'body...',
        _id: 'note:4eeb997c',
        _rev: '8-d18201be3336c70979c6a375b497b3a7'
      }
    },
    ...
  ]
}
```

---

## Create a note ID `createId(): string`

Creates new note ID which is String

### Parameters

No parameters

### Returns

Returns a new note ID.

```js
const db = env.localDB
const noteId = await db.notes.createId()
```

```json title="Response"
"note:8eea9f7c"
```

## Validate a note ID `validateDocId(): boolean`

Tests if the given `docId` is a valid note ID

### Parameters

- **docId** (string, required)

  A document ID to validate

### Returns

Returns `true` if valid

```js
const db = env.localDB
const isValid = await db.notes.validateDocId('note:8eea9f7c')
```

```json title="Response"
true
```

---

## Create or update a note `put(doc)`

Create a new note or update an existing note.
If the note already exists, you must specify its revision `_rev`, otherwise a conflict will occur.

### Parameters

- **doc** (object, required)

  A Note data to store

### Returns

It throws an `InvalidDataError` if the given doc was invalid.
The response contains the `id` of the document, the new `rev`, and an `ok` to reassure you that everything is okay.

```js
const db = env.localDB
const result = await db.notes.put({
  "_id": "note:BKzzd8iGK",
  "doctype": "markdown",
  "bookId": "book:tjnPbJakw",
  "createdAt": 1589165355584,
  "updatedAt": 1592532006000,
  "status": "active",
  "share": "private",
  "numOfTasks": 0,
  "numOfCheckedTasks": 0,
  "pinned": true,
  "title": "hello",
  "body": "example note",
  "tags": ["tag:HyBgJ94gx", "tag:h11OMPbSs"]
})
```

```json title="Response"
{
  "ok": true,
  "id": "note:BKzzd8iGK",
  "rev": "1-a6157a5ea545c99b00ff904eef05fd9f"
}
```

---

## Remove a note `remove(docId)`

Deletes a note with the given note ID.

### Parameters

- **docId** (string, required)

  A note ID to delete.

### Returns

The response contains the `id` of the document, the new `rev`, and an `ok` to reassure you that everything is okay.

```js
const db = env.localDB
const result = await db.notes.remove("note:BKzzd8iGK")
```

```json title="Response"
{
  "ok": true,
  "id": "note:BKzzd8iGK",
  "rev": "2-9af304be281790604d1d8a4b0f4c9adb"
}
```

---

## Remove a batch of notes `removeBatch(docIds)`

Deletes multiple notes with the given note IDs.

### Parameters

- **docIds** (string\[], required)

  An Array of note IDs to delete.

### Returns

Returns an array of new revision IDs.

```js
const db = env.localDB
const result = await db.notes.removeBatch(["note:BKzzd8iGK", "note:8eea9f7c"])
```

```json title="Response"
[
  {
    "ok": true,
    "id": "note:BKzzd8iGK",
    "rev": "2-9af304be281790604d1d8a4b0f4c9adb"
  },
  {
    "ok": true,
    "id": "note:8eea9f7c",
    "rev": "3-faf004b42827906a4dadbabb0fbc9aff"
  }
]
```

---

## Count number of notes `countAll()`

Counts a number of notes in the database.

### Parameters

No parameters.

### Returns

Returns a number of notes stored in the database.

```js
const db = env.localDB
const num = await db.notes.countAll()
```

```json title="Response"
21
```

---

## List notes within a specific notebook `findInBook(bookId, options)`

Retrieves notes associated with given notebook ID.

### Parameters

- **bookId** (string, required)

  A notebook ID to find.
- **options** (object)

  List options. See [:all](#list-all-notes) for details.

### Returns

Returns a query result.

```js
const db = env.localDB
const num = await db.notes.findInBook('book:tjnPbJakw')
```

```js title="Response"
{
  query: {
    index: 'notes',
    bookId: 'book:tjnPbJakw'
  },
  totalRows: 9357,
  cursor: {
    index: 'notes',
    bookId: 'book:tjnPbJakw',
    limit: 50,
    skip: 50
  },
  includeDocs: true,
  rows: [
    {
      doc: {
        doctype: 'markdown',
        updatedAt: 1461564004766,
        createdAt: 1461563995746,
        bookId: 'book:tjnPbJakw',
        status: 'none',
        numOfTasks: 0,
        numOfCheckedTasks: 0,
        title: 'title...',
        body: 'body...',
        _id: 'note:4eeb997c',
        _rev: '8-d18201be3336c70979c6a375b497b3a7'
      }
    },
    ...
  ]
}
```

---

## List notes with a specific tag `findWithTag(tagId, options)`

Retrieves notes associated with the given tag ID.

### Parameters

- **tagId** (string, required)

  A tag ID to find.
- **options** (object)

  List options. See [:all](#list-all-notes) for details.

### Returns

Returns a query result.

```js
const db = env.localDB
const num = await db.notes.findWithTag('tag:4eeb997c')
```

```js title="Response"
{
  query: {
    index: 'notes',
    tagId: 'tag:4eeb997c'
  },
  totalRows: 9357,
  cursor: {
    index: 'notes',
    tagId: 'tag:4eeb997c',
    limit: 50,
    skip: 50
  },
  includeDocs: true,
  rows: [
    {
      doc: {
        doctype: 'markdown',
        updatedAt: 1461564004766,
        createdAt: 1461563995746,
        bookId: 'book:tjnPbJakw',
        status: 'none',
        numOfTasks: 0,
        numOfCheckedTasks: 0,
        title: 'title...',
        body: 'body...',
        _id: 'note:4eeb997c',
        _rev: '8-d18201be3336c70979c6a375b497b3a7'
      }
    },
    ...
  ]
}
```

---

## List notes with a specific status `findWithStatus(statue, options)`

Retrieves notes with the given note status.

### Parameters

- **status** (string, required)

  A note status, which can be `'none'`, `'active'`, `'onHold'`, `'completed'` or `'dropped'`.
- **options** (object)

  List options. See [:all](#list-all-notes) for details.

### Returns

Returns a query result.

```js
const db = env.localDB
const num = await db.notes.findWithStatus('active')
```

```js title="Response"
{
  query: {
    index: 'notes',
    status: 'active'
  },
  totalRows: 9357,
  cursor: {
    index: 'notes',
    status: 'active',
    limit: 50,
    skip: 50
  },
  includeDocs: true,
  rows: [
    {
      doc: {
        doctype: 'markdown',
        updatedAt: 1461564004766,
        createdAt: 1461563995746,
        bookId: 'book:tjnPbJakw',
        status: 'active',
        numOfTasks: 0,
        numOfCheckedTasks: 0,
        title: 'title...',
        body: 'body...',
        _id: 'note:4eeb997c',
        _rev: '8-d18201be3336c70979c6a375b497b3a7'
      }
    },
    ...
  ]
}
```

---

## Count notes matching filters `count(query)`

Counts the notes that a list with the same filters would contain.
Like the list methods, it excludes notes in the trash and notes whose status is `'completed'` or `'dropped'` unless the filters specify them.

### Parameters

- **query** (object)

  Object with the following keys:
  - **bookId** (string | string\[])

    A notebook ID, or an array of notebook IDs.
  - **tagId** (string)

    A tag ID.
  - **status** (string | string\[])

    A note status, or an array of note statuses.

### Returns

Returns the number of matching notes.

```js
const db = env.localDB
const num = await db.notes.count({ tagId: 'tag:4eeb997c' })
```

```json title="Response"
12
```

---

## List all note IDs in a notebook `findAllIdsInBook(bookId, options)`

Retrieves the IDs of every note in the given notebook, including notes whose status is `'completed'` or `'dropped'`.

### Parameters

- **bookId** (string, required)

  A notebook ID to find.
- **options** (object)

  Object with the following keys:
  - **includeChildren** (boolean)

    Whether to include notes in the descendant notebooks.
  - **tagId** (string)

    A tag ID to narrow the notes down to.

### Returns

Returns an array of note IDs.

```js
const db = env.localDB
const noteIds = await db.notes.findAllIdsInBook('book:tjnPbJakw', {
  includeChildren: true
})
```

```json title="Response"
["note:4eeb997c", "note:BKzzd8iGK"]
```

---

## List all note IDs with a tag `findAllIdsWithTag(tagId)`

Retrieves the IDs of every note with the given tag, including notes in the trash, templates, and notes whose status is `'completed'` or `'dropped'`.

### Parameters

- **tagId** (string, required)

  A tag ID to find.

### Returns

Returns an array of note IDs.

```js
const db = env.localDB
const noteIds = await db.notes.findAllIdsWithTag('tag:4eeb997c')
```

```json title="Response"
["note:4eeb997c", "note:BKzzd8iGK"]
```
