# Class: DataEntity

## DataEntity

#### new DataEntity(DataEntityConfig)

Data Entity API

  When composing web applications using this library, we strongly believe the data design and plan should be the entry point of your software design.
  The Entity Relationship diagram shall to be one of the initial documents you should to design before starting to write your software.
  We assume the Entity Relationship and Data Entity models as technique and paradigm to design the application data.
  If you have no idea of how agile you could to design your ER diagram, please take a look at some tools like Moon Modeler
  Every Data Entity in the system has it own encapsulated properties and methods that cares about where entity data is writen to and read from.
  The DataEntity relies on the application instance (passed to it constructor) to access the available data transports.
  It means you can not use DataEntity prior starting a data transport layer.
  This class is not for direct usage in your project, unless you are a core developer or want to understand what happens behind the scenes, you should consider to take a look at the `Foundation` class.

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---

  `DataEntityConfig`

  object

  Data Entity configuration

  ###### Properties

  Name | Type | Description
  --- | --- | ---
  `foundation` | string | Provide Accesss to Foundation scope
  `entity` | string | Data entity name which this dataEntity instance is handling
  `strategy` | boolean | Data transport strategy
  `schema` | boolean | Data schema for this Data Entity abstraction. Do not declare the params __id and _id inside your schemas.

  Author:
    - Eduardo Perotta de Almeida
  Source:
    - DataEntity.js, line 7

  ##### Example

      import { Schema } from '../foundation/Foundation'

      const schema = new Schema({
        // do not declare __id
        // do not declare _id
        name: {
          type: String,
          required: true,
          index: true
        },
        address: {
          type: String,
          required: true,
          index: true
        },
        email: {
          type: String,
          required: true,
          index: true
        },
        cards: {
          type: [],
          required: true
        }
      })

      const Customer = new DataEntity({
        foundation, // Foundation instance, object
        entity: 'Customer', // entity name, string
        strategy: 'offline', // data strategy, string
        schema // data schema, a mongoose like schema
      })

      // listen to add Customer Data event on Data API
      const onAddDocEventListener = Customer.on(
        'add',
        function(eventObj){
          const { error, document, foundation, data } = eventObj
          // do something like to update the component View state Based On Information from Incoming Event
          component.setState({ propertyName: newValue }) // React:
          component.$set(component.data, 'propertyName', newValue) // Vue:

        }
      )
      // listen to edit Customer Data event on Data API
      const onEditDocEventListener = Customer.on(
        'edit',
        function (eventObj) {
          const { error, document, foundation, data } = eventObj
          // do something like to update the component View state Based On Information from Incoming Event
          component.setState({ propertyName: newValue }) // React:
          component.$set(component.data, 'propertyName', newValue) // Vue:
        }
      )
      // listen to delete Customer Data event on Data API
      const onDeleteDocEventListener = Customer.on(
        'delete',
        function (eventObj) {
          const { error, document, foundation, data } = eventObj
          // do something like to update the component View state Based On Information from Incoming Event
          component.setState({ propertyName: newValue }) // React:
          component.$set(component.data, 'propertyName', newValue) // Vue:
        }
      )

      // Stop to listen to events to avoid memory leak or others kind of problems
      // like to change the state of an unmounted component.
      // Do something like this -> before component unmount OR before window unload
      Customer.stopListenTo(onAddDocEventListener)
      Customer.stopListenTo(onEditDocEventListener)
      Customer.stopListenTo(onDeleteDocEventListener)

### Extends

- EventSystem

### Members

#### <static> strategy :getter

Gets the data strategy currently being used.

  Gets the data strategy currently being used

  ##### Type:

  - getter
  Source:
    - DataEntity.js, line 148

  ##### Example

      console.log(DataEntity.strategy)

### Methods

#### <static> _listenToAllOtherSessionsStateChanges()

PRIVATE - Listen to data state changes on every Application session.

  Listen to data state change event incoming from every other Application session and communicates to every subscriber tied to this session.
  The application scope is the browser running the application.
  Every tab is considered a session.
  Internally it triggers all events related to data change events, except if the source, the session which originated the event, is the same that is receiving the event
  It does not rely on network to propagate the changes.
  Source:
    - DataEntity.js, line 517

  ##### Example

      this.#_listenToAllOtherSessionsStateChanges()

#### <static> _sendStateChangeToAllOtherSessions(state)

PRIVATE - Sends data state changes information to every other current application session.

  The application scope is the browser running the application.
  Every tab is considered a session.
  It can not rely on network.

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---

  `state`

  object

  Object containing all information about the state

  ###### Properties

  Name | Type | Description
  --- | --- | ---
  `data` | object | The modified data, default is null if not provided
  `error` | object | string | The returned error when trying to modify the data, default is null if not provided
  `document` | object | The raw object used as value to get the new data state, default is {} if not provided

  Source:
    - DataEntity.js, line 555

  ##### Example

      this.#_sendStateChangeToAllOtherSessions({
                action: 'add',
                data: {...newDocument},
                error: null,
                document: {...originalDocument}
              })

#### <static> _triggerAddEvents(eventPayload)

PRIVATE - Triggers all events related to 'add document' event.

  PRIVATE - Triggers all events related to 'add document' event

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---

  `eventPayload`

  object

  Object containing all information about the event

  ###### Properties

  Name | Type | Description
  --- | --- | ---
  `data` | object | The new document inserted into database, default is null if not provided
  `error` | object | string | The returned error from database add request if any, default is null if not provided
  `primaryKey` | number | The primaryKey value of the added document, default is zero if not provided
  `rawObj` | object | The raw document object provided on dataEntity.add(doc) mehod call. Default is {} if not provided.

  Source:
    - DataEntity.js, line 212

#### <static> _triggerDeleteEvents(eventPayload)

PRIVATE - Triggers all events related to 'delete document' event.

  PRIVATE - Triggers all events related to 'delete document' event

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---

  `eventPayload`

  object

  Object containing all information about the event

  ###### Properties

  Name | Type | Description
  --- | --- | ---
  `data` | object | A object containing the __id property of the deleted document, default is null if not provided
  `error` | object | string | The returned error from database edit request if any, default is null if not provided
  `primaryKey` | number | The primaryKey value of the deleted document, default is zero if not provided

  Source:
    - DataEntity.js, line 364

#### <static> _triggerEditEvents(eventPayload)

PRIVATE - Triggers all events related to 'edit document' event.

  PRIVATE - Triggers all events related to 'edit document' event

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---

  `eventPayload`

  object

  Object containing all information about the event

  ###### Properties

  Name | Type | Description
  --- | --- | ---
  `data` | object | The new document updated into database, default is null if not provided
  `error` | object | string | The returned error from database edit request if any, default is null if not provided
  `primaryKey` | number | The primaryKey value of the edited document, default is zero if not provided
  `rawObj` | object | The raw document object provided on dataEntity.edit(primaryKey, doc) mehod call. Default is {} if not provided.

  Source:
    - DataEntity.js, line 300

#### <async, static> add(doc)

add a new document to the storage.

  add a new document to the storage

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `doc` | object | A valid document validated against mongoose schema

  Source:
    - DataEntity.js, line 171

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Created document
    Type
      object

  ##### Example

      const doc = {
        name: 'Eduardo Almeida',
        address: 'Av. Beira Mar. Praia do Morro, Guarapari - ES. Brazil.',
        email: 'web2solucoes@gmail.com',
        cards: []
      }
      const { data, error } = await Customer.add(doc)

#### <async, static> count(query)

count all documents based on the given query.

  count all documents based on the given query

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `query` | object | The query object to count documents

  Source:
    - DataEntity.js, line 489

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Documents counter
    Type
      number

  ##### Example

      User.count({
                $or: [{ age: { $lt: 23, $ne: 20 } }, { lastname: { $in: ['Fox'] } }]
              })

#### <async, static> delete(primaryKey)

delete a document from the storage.

  delete a document from the storage

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `primaryKey` | string | number | The primary key value of the desired document

  Source:
    - DataEntity.js, line 337

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Deleted document
    Type
      object

#### <async, static> edit(primaryKey, doc)

Edit a document on the storage.

  Edit a document on the storage

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `primaryKey` | string | number | The primary key value of the desired document
  `doc` | object | A valid document validated against mongoose schema

  Source:
    - DataEntity.js, line 243

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Edited document
    Type
      object

  ##### Example

      const doc = {
        __id: 1,
        _id: '601cb8d8623dc60000ee3c24',
        name: 'Eduardo Almeida',
        address: 'Av. Beira Mar. Praia do Morro, Guarapari - ES. Brazil.',
        email: 'web2solucoes@gmail.com',
        cards: []
      }
      const { data, error } = await Customer.edit(doc.__id, doc)

#### <async, static> find(query, pagination)

find all documents based on the given query.

  find all documents based on the given query

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `query` | object | null | The query object to search documents

  `pagination`

  object

  Pagination object. If not provided will assume internaly set pagination.

  ###### Properties

  Name | Type | Description
  --- | --- | ---
  `offset` | number | Offset. Default 0.
  `limit` | number | Limit. Default 30.

  Source:
    - DataEntity.js, line 453

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Array of Found documents
    Type
      array

  ##### Example

      User.find({
                $or: [{ age: { $lt: 23, $ne: 20 } }, { lastname: { $in: ['Fox'] } }]
              })

#### <async, static> findAll()

find all documents.

  find all documents
  Source:
    - DataEntity.js, line 429

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Array of Found documents
    Type
      array

#### <async, static> findById(primaryKey)

find a document from the storage by ID.

  find a document from the storage by ID

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `primaryKey` | string | number | The primary key value of the desired document

  Source:
    - DataEntity.js, line 398

  ##### Returns:

  - signature - Default methods signature format { error, data }
    Type
      object
  - signature.error - Execution error
    Type
      string | object
  - signature.data - Found document
    Type
      object

#### <static> Model(doc, schema)

create a Data Model based on given document.

  create a Data Model based on given document

  ##### Parameters:

  Name | Type | Description
  --- | --- | ---
  `doc` | object | A valid document validated against mongoose schema
  `schema` | object | Mongoose based schema

  Source:
    - DataEntity.js, line 159

  ##### Returns:

  model - Mongoose document
  Type
    object

#### Search results