# Concept interaction

## Overview

`Concept` is a term describing different kind of "tags" that can be linked to an article. Concepts can be of different types which ads a way to separate tags (or metadata) for different needs.

An article can be linked to zero, one or many concepts, with different types. And each link points to a specific concept item in the backend repository.

Each linked concept is represented as a link tag in the article document.

```markup
<link rel="subject" title="Elitserien" type="x-im/category" uuid="b3c8f46f-00db-4e23-a98f-69494582aacc" />
```

Full documentation on `Concepts` [can be found here](https://docs.navigaglobal.com/writer/6.2.2/developer-guide/infomaker-newsml/imnml-conceptitem)

## Interacting with concepts

All communication with the article document object dealing with concepts should go through the `ConceptService` class imported directly from the `writer`.

```javascript
// Import the ConceptService
import { ConceptService } from 'writer'

// Get all current concepts from the article, of a specific type
const articleConcepts = ConceptService.getArticleConceptsByType('x-im/author')

// Get all concepts of a specific type from repository
const repositoryConcepts = ConceptService.getRemoteConceptsByType('x-im/category')

// Get all additional properties like broader, assiciated-with, long and short description etc for a concept
const enhancedConcept = await ConceptService.fetchConceptItemProperties({ uuid: 'xyz' })

// text-search for conceptSuggestions
const conceptSuggestions = await ConceptService.searchForConceptSuggestions('x-im/category', 'searchterm', subtypesArray = [])
const conceptSuggestions = await ConceptService.searchForConceptSuggestions(
    'x-im/place',
    'Kalmar', /* <-- this is where the search term goes */
    subtypesArray = ['x-im/position', 'x-im/polygon']
)

/**
 * Create a new concept and add it to the document
 *
 * You will need to use the propertyMap to e sure that you object
 * gets the configured properties for the current backend
 **/
const propertyMap = ConceptService.getPropertyMap()
const newConceptItem = {}
newConceptItem[propertyMap.uuid] = 'uuid'
newConceptItem[propertyMap.ConceptImTypeFull] = 'x-im/channel'
newConceptItem[propertyMap.ConceptName] = 'My new channel'

// Add the new concept
ConceptService.addArticleConcept(newConceptItem)

// Or update an existing one
ConceptService.updateArticleConcept(updatedConceptItem)

// Or remove it
ConceptService.removeArticleConceptItem(conceptItem)
```

### Operations

The `ConceptService` exposes an API to perform Concept related operation, like searching for concepts in the backend repository, or adding, updating or removing concepts in the article document.

### Events

To hook into the different life cycle events of concepts, `ConceptsService` exposes a way to register callback functions on a specific type and event (here called operations).

Example of how to bind a callback function that will be fired after a new Category concept has been added to the article can be seen below. The callback will receive the new concept object as argument.

```javascript
ConceptService.on(
    'x-im/category',
    ConceptService.operations.ADDED,
    this.handleNewCategory
)
```

The available operations are:

```javascript
{
    ADD: 1,
    ADDED: 2,
    UPDATE: 3,
    UPDATED: 4,
    REMOVE: 5,
    REMOVED: 6
}
```
