---
Added: v2.0.0
Status: Active
---
# Tasklist Service

Manage Task Instances. 

## Importing

```ts
import { TaskListService, TaskDetailsModel, TaskQueryRequestRepresentationModel, TaskListModel, Form } from '@alfresco/adf-process-services';
import { TaskUpdateRepresentation } from 'alfresco-js-api';

export class SomePageComponent implements OnInit {

  constructor(private tasklistService: TaskListService) {
  }
```

## Methods

#### getTaskDetails(taskId: string): Observable`<TaskDetailsModel>`

Get Task Instance metadata for passed in Task Instance ID:

```ts
const taskInstanceId = '15303';
this.tasklistService.getTaskDetails(taskInstanceId).subscribe( (taskInstance: TaskDetailsModel) => {
    console.log('TaskInstance: ', taskInstance);
}, error => {
    console.log('Error: ', error);
});
```

The `taskInstanceId` refers to a Task Instance identifier in APS.  
The returned `taskInstance` object is of type `TaskDetailsModel` and looks like in this sample:

    adhocTaskCanBeReassigned: false
    assignee: UserProcessModel {pictureId: null, id: 1, email: "admin@app.activiti.com", firstName: null, lastName: "Administrator"}
    category: null
    created: Wed Oct 11 2017 09:07:14 GMT+0100 (BST) {}
    description: null
    dueDate: null
    duration: null
    endDate: null
    executionId: "11337"
    formKey: "9"
    id: "15303"
    initiatorCanCompleteTask: false
    involvedPeople: []
    managerOfCandidateGroup: false
    memberOfCandidateGroup: false
    memberOfCandidateUsers: false
    name: "Clarify Invoice - Invoice-20302.pdf"
    parentTaskId: null
    parentTaskName: null
    priority: 50
    processDefinitionCategory: "http://www.activiti.org/processdef"
    processDefinitionDeploymentId: "18"
    processDefinitionDescription: "This is a simple invoice approval process that allows a person to assign a dedicated approver for the the invoice. It will then be routed to the Accounting department for payment preparation. Once payment is prepared the invoice will be stored in a specific folder and an email notification will be sent."
    processDefinitionId: "InvoiceApprovalProcess:2:21"
    processDefinitionKey: "InvoiceApprovalProcess"
    processDefinitionName: "Invoice Approval Process"
    processDefinitionVersion: 2
    processInstanceId: "11337"
    processInstanceName: null
    processInstanceStartUserId: "1"
    taskDefinitionKey: "clarifyInvoice"

#### getTaskChecklist(id: string): Observable`<TaskDetailsModel[]>`

Get all the sub-task instances for a Task Instance, also called the check list: 

```ts
const parentTaskId = '15303';
this.tasklistService.getTaskChecklist(parentTaskId).subscribe( (subTasks: TaskDetailsModel[]) => {
  console.log('Sub Tasks: ', subTasks);
}, error => {
  console.log('Error: ', error);
});
```

The response is an array of `TaskDetailsModel` representing the sub-tasks:

    Sub Tasks: 
        0:
            adhocTaskCanBeReassigned: false
            assignee: UserProcessModel {pictureId: null, id: 1, email: "admin@app.activiti.com", firstName: null, lastName: "Administrator"}
            category: "2"
            created: "2017-10-29T07:29:28.881+0000"
            description: null
            dueDate: null
            duration: null
            endDate: null
            executionId: null
            formKey: null
            id: "74745"
            initiatorCanCompleteTask: false
            involvedPeople: undefined
            managerOfCandidateGroup: false
            memberOfCandidateGroup: false
            memberOfCandidateUsers: false
            name: "Double check invoice amount"
            parentTaskId: "15303"
            parentTaskName: "Clarify Invoice - Invoice-10292.pdf"
            priority: 50
            processDefinitionCategory: null
            processDefinitionDeploymentId: null
            processDefinitionDescription: null
            processDefinitionId: null
            processDefinitionKey: null
            processDefinitionName: null
            processDefinitionVersion: 0
            processInstanceId: null
            processInstanceName: null
            processInstanceStartUserId: null
            taskDefinitionKey: null
        1 :
            {processDefinitionVersion: 0, id: "74746", name: "Verify with the person that did the purchase", priority: 50, assignee: UserProcessModel, …}

Looking at the `TaskDetailsModel` for a sub-task we can see that it has a parent task ID that matches what we specified
when calling this method.

#### getTasks(requestNode: TaskQueryRequestRepresentationModel): Observable`<TaskListModel>`

Get tasks matching passed in query definition:

```ts
const taskQuery: TaskQueryRequestRepresentationModel = {
  appDefinitionId: '2',
  processInstanceId: null,
  processDefinitionId: null,
  text: null,
  assignment: null,
  state: 'open',
  sort: 'created_asc',
  page: 0,
  size: 5,
  start: null
};
this.tasklistService.getTasks(taskQuery).subscribe( (taskListModel: TaskListModel) => {
    console.log('Task List Model: ', taskListModel);
}, error => {
    console.log('Error: ', error);
});
```

In the above example we query for all Task Instances associated with a Process Application with
ID 2. We set `size` to 5, which means that the query will return max 5 task instances. 

We can mix and match the query parameters to narrow down the task list that is returned. 
If you are just interested in Task Instances related to a specific Process Instance, 
then set the `processInstanceId`. If you want to see all tasks related to a specific type of processes, 
then you should set the `processDefinitionId` property. 

You can use the `state` property to define if only `completed` or only `open` tasks should be returned. If you 
specify `null` for state then `open` will be assumed.

The `assignment` property can be used to filter tasks based on how they are assigned (or not assigned yet).
Use `assignee` if you are interested in tasks that are assigned to a user. If you want to see 
pooled tasks (i.e. tasks that needs to be claimed by a user), then use `candidate`.

A `TaskListModel` object is returned for a successful query and the `data` property is an array of
`TaskDetailsModel`:

    data:
        0: {id: "75010", name: "Approve Invoice  - Invoice-10202.pdf", description: null, category: null, assignee: {…}, …}
        1: {id: "74746", name: "Verify with the person that did the purchase", description: null, category: "2", assignee: {…}, …}
        2: {id: "74745", name: "Double check invoice amount", description: null, category: "2", assignee: {…}, …}
        3: {id: "20686", name: "Sample checklist task 1", description: null, category: "2", assignee: {…}, …}
        4: {id: "15303", name: "Clarify Invoice - Invoice-20302.pdf", description: null, category: null, assignee: {…}, …}
    length: 5
    size: 5
    start: 0
    total: 10

We can see that this query resulted in 10 tasks (see `total`), but only 5 were returned as we set `size` to `5`.

#### getTotalTasks(requestNode: TaskQueryRequestRepresentationModel): Observable`<any>`

Get total number of tasks matching passed in query definition:

```ts
const taskQuery: TaskQueryRequestRepresentationModel = {
  appDefinitionId: '2',
  processInstanceId: null,
  processDefinitionId: null,
  text: null,
  assignment: null,
  state: 'open',
  sort: 'created_asc',
  page: 0,
  size: 5,
  start: null
};
this.tasklistService.getTotalTasks(taskQuery).subscribe( (response: any) => {
  console.log('Total: ', response);
}, error => {
  console.log('Error: ', error);
});
```

This is pretty much the same type of query as the `getTasks` method, except that here we just 
return how many Task Instances it matched in the `total` property:

    data:[]
    size: 0
    start: 0
    total: 10

When you call this method it always sets the `size` property to `0`.

#### findTasksByState(requestNode: TaskQueryRequestRepresentationModel, state?: string): Observable`<TaskListModel>`

Find and return Task Instances by state `open` or `completed` and query model:

```ts
const taskState = 'open';
const taskQuery: TaskQueryRequestRepresentationModel = {
  appDefinitionId: '2',
  processInstanceId: null,
  processDefinitionId: null,
  text: null,
  assignment: null,
  state: 'open',
  sort: 'created_asc',
  page: 0,
  size: 5,
  start: null
};

this.tasklistService.findTasksByState(taskQuery, taskState).subscribe( (taskList: TaskListModel) => {
  console.log('Task list: ', taskList);
}, error => {
  console.log('Error: ', error);
});
```

The number of tasks that are returned is controlled by the `size` property.

This is a convenience method on top of the `getTasks` method. It overwrites the `requestNode.state` property 
with passed in `state` before making the call to `getTasks`.
For an example of the response see the `getTasks` method.

#### findAllTaskByState(requestNode: TaskQueryRequestRepresentationModel, state?: string): Observable`<TaskListModel>`

Find and return all Task Instances by state `open` or `completed` and query model:

```ts
const taskState = 'open';
const taskQuery: TaskQueryRequestRepresentationModel = {
  appDefinitionId: '2',
  processInstanceId: null,
  processDefinitionId: null,
  text: null,
  assignment: null,
  state: 'open',
  sort: 'created_asc',
  page: 0,
  size: 5,
  start: null
};

this.tasklistService.findAllTaskByState(taskQuery, taskState).subscribe( (taskList: TaskListModel) => {
  console.log('Task list: ', taskList);
}, error => {
  console.log('Error: ', error);
});
```

This is a convenience method on top of the `getTasks` method. It overwrites the `requestNode.state` property with 
passed in `state` before making any other calls. Before making the `getTasks` call it will first call the 
`getTotalTasks` method to get the total number of tasks that match query and state. It then overwrite the 
`requestNode.size` with the total so all matching tasks are returned when finnally making the `getTasks` call.

**Note** that this can return a lot of data if you are not careful.

#### findAllTasksWithoutState(requestNode: TaskQueryRequestRepresentationModel): Observable`<TaskListModel>`

Find and return all Task Instances that matches query model, regardless of state:

```ts
const taskQuery: TaskQueryRequestRepresentationModel = {
  appDefinitionId: '2',
  processInstanceId: null,
  processDefinitionId: null,
  text: null,
  assignment: null,
  state: null,
  sort: 'created_asc',
  page: 0,
  size: 5,
  start: null
};

this.tasklistService.findAllTasksWithoutState(taskQuery).subscribe( (taskList: TaskListModel) => {
  console.log('Task list: ', taskList);
}, error => {
  console.log('Error: ', error);
});
```

This method can be used when you have a task query that should return all tasks regardless of the state they 
are in. You cannot achieve this with the `getTasks` method. If you specify a `size` it is overwritten.
Internally it basically calls `findTasksByState(requestNode, 'open')` and 
`findAllTaskByState(requestNode, 'completed')`.

**Note** that this can return a lot of data if you are not careful.

#### assignTaskByUserId(taskId: string, userId: number): Observable`<TaskDetailsModel>`

Assign a Task Instance to a user via the User ID:

```ts
const taskId = '15303';
const userId = 1;
this.tasklistService.assignTaskByUserId(taskId, userId).subscribe( (taskInstance: TaskDetailsModel) => {
  console.log('Task instance: ', taskInstance);
}, error => {
  console.log('Error: ', error);
});
```

The user ID identifies a User in APS.

#### assignTask(taskId: string, requestNode: any): Observable`<TaskDetailsModel>`

Assign a task to a user via a user object with an `id` property, for example:

```ts
const taskId = '15303';
const user = { id: 1, email: 'admin@app.activiti.com', firstName: 'APS', lastName: 'Admin' };
this.tasklistService.assignTask(taskId, user).subscribe( (taskInstance: TaskDetailsModel) => {
  console.log('Task instance: ', taskInstance);
}, error => {
  console.log('Error: ', error);
});
```

This method does the same as the `assignTaskByUserId` method, the only difference is that this
method can be used when you have an object where the User ID is contained in an `id` property.

#### claimTask(taskId: string): Observable`<TaskDetailsModel>`

Claim a pooled task (i.e. candidate task) as current user so it can be worked on and later on completed: 

```ts
const taskId = '15368'; 
this.tasklistService.claimTask(taskId).subscribe( (taskInstance: TaskDetailsModel) => {
  console.log('Task instance: ', taskInstance);
}, error => {
  console.log('Error: ', error);
});
```

The response will be `null` if the task was claimed successfully.

The task assignment changes from `candidate` to `assignee`.

#### unclaimTask(taskId: string): Observable`<TaskDetailsModel>`

Return a claimed task to the pool (i.e. make it a candidate task): 

```ts
const taskId = '15368'; 
this.tasklistService.unclaimTask(taskId).subscribe( (taskInstance: TaskDetailsModel) => {
  console.log('Task instance: ', taskInstance);
}, error => {
  console.log('Error: ', error);
});
```

The task assignment changes from `assignee` to `candidate`.

#### completeTask(taskId: string)

Complete a Task Instance as current user and progress Process Instance:

```ts
const taskId = '15176';
this.tasklistService.completeTask(taskId);
```

This only works if the Task Instance has only one Outcome (i.e. the default `Complete` one). 
If the Task Instance has multiple Outcomes, such as Approve and Reject, then this method does not
work, and the Task Instance has to be completed via its associated form. Otherwise you will see an error such as:

_ERROR Error: Uncaught (in promise): Error: {"message":"Task must be completed using it's form","messageKey":"GENERAL.ERROR.BAD-REQUEST"}_

#### updateTask(taskId: any, updated): Observable`<TaskDetailsModel>`

Update name, description, and due date for a Task Instance:

```ts
const taskId = '80002';
const updateData: TaskUpdateRepresentation = {
    description: 'Updated description',
    dueDate: new Date(2018, 1, 10, 11, 0, 0, 0),
    name: 'Updated name'
};
this.tasklistService.updateTask(taskId, updateData).subscribe( (updatedTaskDetails: TaskDetailsModel) => {
  console.log('Updated task: ', updatedTaskDetails);
}, error => {
  console.log('Error: ', error);
});
```

The response is all info about the updated Task Instance, in this example a stand-alone task was updated so there
is no associated process:

    adhocTaskCanBeReassigned: false
    assignee: undefined
    category: null
    created: Mon Nov 13 2017 16:34:49 GMT+0000 (GMT) {}
    description: "Updated description"
    dueDate: Sat Feb 10 2018 11:00:00 GMT+0000 (GMT) {}
    duration: NaN
    endDate: null
    executionId: null
    formKey: "5005"
    id: "80002"
    initiatorCanCompleteTask: false
    managerOfCandidateGroup: false
    memberOfCandidateGroup: false
    memberOfCandidateUsers: false
    name: "Updated name"
    parentTaskId: null
    parentTaskName: null
    priority: 50
    processDefinitionCategory: null
    processDefinitionDeploymentId: null
    processDefinitionDescription: null
    processDefinitionId: null
    processDefinitionKey: null
    processDefinitionName: null
    processDefinitionVersion: 0
    processInstanceId: null
    processInstanceName: null
    processInstanceStartUserId: null
    taskDefinitionKey: null

#### createNewTask(task: TaskDetailsModel): Observable`<TaskDetailsModel>`

Create a new stand-alone Task Instance that is not associated with a Process Instance:

```ts
const taskDetails = new TaskDetailsModel({
  name: 'Some Task',
  description: 'A new stand-alone task'
});

this.tasklistService.createNewTask(taskDetails).subscribe( (createdTaskDetails: TaskDetailsModel) => {
  console.log('Created task details: ', createdTaskDetails);
}, error => {
  console.log('Error: ', error);
});
```

In this case we are creating a disconnected Task Instance that is not associated with a form (i.e. `formKey: null`) 
and that is not assigned to a user (i.e. `assignee: null`).

The response looks like this, we can see that an ID was generated for the Task Instance:

    Created task details:  
        adhocTaskCanBeReassigned: false
        assignee: null
        category: null
        created: Mon Nov 13 2017 16:34:49 GMT+0000 (GMT) {}
        description: "A new stand-alone task"
        dueDate: null
        duration: null
        endDate: null
        executionId: null
        formKey: null
        id: "80002"
        initiatorCanCompleteTask: false
        involvedPeople: undefined
        managerOfCandidateGroup: false
        memberOfCandidateGroup: false
        memberOfCandidateUsers: false
        name: "Some Task"
        parentTaskId: null
        parentTaskName: null
        priority: 50
        processDefinitionCategory: null
        processDefinitionDeploymentId: null
        processDefinitionDescription: null
        processDefinitionId: null
        processDefinitionKey: null
        processDefinitionName: null
        processDefinitionVersion: 0
        processInstanceId: null
        processInstanceName: null
        processInstanceStartUserId: null
        taskDefinitionKey: null

See the `attachFormToATask` method for how to attach a form to the User Task. And see the `assignTaskByUserId` method
for how to assign a user to the new Task Instance.

#### attachFormToATask(taskId: string, formId: number): Observable`<any>`

Attach a form to a User Task:

```ts
const taskId = '80002'; 
const formId = 5005;
this.tasklistService.attachFormToATask(taskId, formId).subscribe( (response: any) => {
  console.log('Assign form response: ', response);
}, error => {
  console.log('Error: ', error);
});
```

In this case we need to have a task created and know the ID for it, such as with the `createNewTask` method.
We also need to have a form defined in APS and know the ID for it (you can see the ID for a form in the URL 
in APS when you work with it). See the `getFormList` method for how fetch a list of available forms.

The response will be `null` if form was attached successfully to task.  

#### getFormList(): Observable`<Form []>`

Get a list of the available reusable forms:

```ts
this.tasklistService.getFormList().subscribe( (formList: Form[]) => {
  console.log('Available forms: ', formList);
}, error => {
  console.log('Error: ', error);
});
```

A successful response looks like this:

    Available forms:  

    0:  
        id: 5005
        name: "Name Info"
    1: {name: "cm:folder", id: 3012}
    2: {name: "Alfresco Node Form", id: 3011}
    3: {name: "Employee", id: 3010}

The form id property can be used with the `attachFormToATask` method.

**Note**. Referenced forms that are associated with specific tasks in a process are not included in this list. 
Only reusable forms are included.

#### addTask(task: TaskDetailsModel): Observable`<TaskDetailsModel>`

Add a Sub-Task (i.e. checklist task) to a parent Task Instance:

```ts
const parentTaskId = '80002';
const subTaskDetails = new TaskDetailsModel({
  parentTaskId: parentTaskId,
  name: 'Check the invoice amount'
});
this.tasklistService.addTask(subTaskDetails).subscribe( (updatedTaskDetails: TaskDetailsModel) => {
  console.log('Sub-task info: ', updatedTaskDetails);
}, error => {
  console.log('Error: ', error);
});
```

The response includes the new sub-task id and also parent task name.
In this example the parent task was just a stand-alone task, so no process information is included:

    adhocTaskCanBeReassigned: false
    assignee: null
    category: null
    created: Tue Nov 14 2017 13:32:41 GMT+0000 (GMT) {}
    description: null
    dueDate: null
    duration: null
    endDate: null
    executionId: null
    formKey: null
    id: "80003"
    initiatorCanCompleteTask: false
    involvedPeople: undefined
    managerOfCandidateGroup: false
    memberOfCandidateGroup: false
    memberOfCandidateUsers: false
    name: "Check the invoice amount"
    parentTaskId: "80002"
    parentTaskName: "Some Task"
    priority: 50
    processDefinitionCategory: null
    processDefinitionDeploymentId: null
    processDefinitionDescription: null
    processDefinitionId: null
    processDefinitionKey: null
    processDefinitionName: null
    processDefinitionVersion: 0
    processInstanceId: null
    processInstanceName: null
    processInstanceStartUserId:null
    taskDefinitionKey: null

#### deleteTask(taskId: string): Observable`<TaskDetailsModel>`

Delete a Sub-Task (i.e. checklist task):

```ts
const taskId = '75100'; // Sub-task ID
this.tasklistService.deleteTask(taskId).subscribe( (taskDetails: TaskDetailsModel) => {
  console.log('Deleted task info: ', taskDetails);
}, error => {
  console.log('Error: ', error);
});
```

**Note**. you can only delete so called checklist tasks with this method. 

#### fetchTaskAuditJsonById(taskId: string): Observable`<any>`

Fetch Task Audit log as JSON for a Task Instance ID:

```ts
const taskId = '15368';
this.tasklistService.fetchTaskAuditJsonById(taskId)
  .subscribe( auditJson => {
    console.log('Task Audit: ', auditJson);
  }, error => {
    console.log('Error: ', error);
  });
```

The response is JSON object with the Task Instance audit log:

    {
      taskId: "15368",
      taskName: "Approve by someone in Accounting",
      processInstanceId: "15361",
      processDefinitionName: "Process With Pooled task",
      processDefinitionVersion: 1,
      …
    }

#### fetchTaskAuditPdfById(taskId: string): Observable`<Blob>`

Fetch Task Audit log as JSON for a Task Instance ID:

```ts
this.tasklistService.fetchTaskAuditPdfById(taskId)
  .subscribe( (auditPdf: Blob) => {
    console.log('Task Audit: ', auditPdf);
  }, error => {
    console.log('Error: ', error);
  });
```

The response is PDF with the Task Instance audit log.
