# DS Server: Merging Documents using the DocumentProcessing Web API in Angular

> This samples shows how to create a template using the document editor and how to merge it using the DS Server DocumentProcessing Web API in Angular.

- **Author:** Bjoern Meyer
- **Published:** 2020-12-22
- **Modified:** 2026-07-17
- **Description:** This samples shows how to create a template using the document editor and how to merge it using the DS Server DocumentProcessing Web API in Angular.
- **4 min read** (663 words)
- **Tags:**
  - Angular
  - DocumentEditor
  - DS Server
  - Release
- **Web URL:** https://www.textcontrol.com/blog/2020/12/22/ds-server-merging-documents-in-angular/
- **LLMs URL:** https://www.textcontrol.com/blog/2020/12/22/ds-server-merging-documents-in-angular/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2020/12/22/ds-server-merging-documents-in-angular/llms-full.txt
- **GitHub Repository:** https://github.com/TextControl/dsserver.angular.documentprocessing

---

The Angular npm packages for DS Server enable the usage of [DocumentEditor](https://docs.textcontrol.com/textcontrol/ds-server/article.gettingstarted.angulareditor.htm) and [DocumentViewer](https://docs.textcontrol.com/textcontrol/ds-server/article.gettingstarted.angularviewer.htm) in Angular applications. The DS Server [DocumentProcessing](https://docs.textcontrol.com/textcontrol/ds-server/webref.documentprocessing.htm) Web API can be used to merge JSON data into created templates to create documents in various formats including Adobe PDF, DOCX and DOC.

This sample shows how to use the document editor and the DocumentProcessing Web API in combination.

### Document Editor

The *app.component.html* view contains the document editor and a button to merge the document:

```
<tx-ds-document-editor
	width="1024px"
	height="600px"
	serviceURL="https://trial.dsserver.io"
	oauthClientID="dsserver.MpgG1D123pueDblkrRTUWASud2Lvl3Xx"
	oauthClientSecret="RQSupqYENd123tYBx5A1nu9HkiDy5LzgO"
	[userNames]="['user1', 'user2']">
</tx-ds-document-editor>

<br />

<input (click)="onClickMergeDocument()" type="button" value="Merge Document" />
```

In the *AppComponent* constructor, dummy merge data is created and loaded into the document editor in the *onDsDocumentEditorLoaded* event.

```
export class AppComponent {

  public _http: HttpClient;
  private _mergeData: any;
  private _dsDocumentProcessing: DsDocumentProcessingModule;

  constructor(http: HttpClient) {
    this._http = http;   
    this._dsDocumentProcessing = new DsDocumentProcessingModule(this._http);

    // dummy merge data
    this._mergeData = [{
      customer: [
        {
          name: "Peter Petersen",
          company: "Software House",
        },
        {
          name: "Jack Developer",
          company: "Software Company",
        }
      ],
    }];
  }

  @HostListener('document:dsDocumentEditorLoaded')
  onDsDocumentEditorLoaded() {
    // attached textControlLoaded event
    TXTextControl.addEventListener("textControlLoaded", () => {
      // fill reporting drop-down structure with dummy merge data
      this._dsDocumentProcessing.loadData(this._mergeData);
    });		
  }

  async onClickMergeDocument() {
    // get the saved document from TXTextControl
    let mergeBody: MergeBody = {
      mergeData: this._mergeData,
      template: await this._dsDocumentProcessing.saveDocument(),
      mergeSettings: null
    };

    this._dsDocumentProcessing.mergeDocument(mergeBody, 'TX');
  };
}

class MergeBody {
  mergeData: any;
  template: any;
  mergeSettings: string;
}
```

This fills the drop-down elements in the *Reporting* ribbon tab to insert merge fields and merge blocks into the document:

![Angular application](https://s1-www.textcontrol.com/assets/dist/blog/2020/12/22/a/assets/angular-app1.webp "Angular application")

### Merge the Document

On the button click event, the Web API is called with a new *MergeBody* object that contains the merge data and the template. In this demo, these functions are separated into the module *DsDocumentProcessingModule*:

```
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpHeaders } from '@angular/common/http';

declare const TXTextControl: any;

@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ]
})

export class DsDocumentProcessingModule {

  private _http: HttpClient;
  private _baseUrl: string = 'https://trial.dsserver.io';
  private _clientId: string = 'dsserver.MpgG1DH4123eDblkrRTUWASud2Lvl3Xx';
  private _clientSecret: string = 'RQSupqYEN123tYBx5A1nu9HkiDy5LzgO';
  private _urlMerge: string = '/documentprocessing/document/merge';
  private _urlOAuth: string = '/oauth';

  constructor(http: HttpClient) {
    this._http = http;   
  }

  private getAccessToken() {

    return new Promise(resolve => {

      let options = {
        headers: new HttpHeaders({
           'Content-Type': 'application/x-www-form-urlencoded',
           'Authorization': 'Basic ' + btoa(this._clientId + ':' + this._clientSecret)
        })
      };
  
      this._http.post<any>(this._baseUrl + this._urlOAuth + "/token",
        'grant_type=client_credentials', 
        options).subscribe(result => {
          resolve(result.access_token);
      }, error => console.error(error));

    });

  }

  async mergeDocument(mergeBody, returnFormat) {

    var accessToken = await this.getAccessToken();

    console.log(accessToken);

    let options = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + accessToken,
      })
    };

    this._http.post<any>(this._baseUrl + this._urlMerge + '?returnFormat=' + returnFormat,
      mergeBody,
      options).subscribe(result => {

        // load the results into TXTextControl
        this.loadDocument(result[0]);
  
    }, error => console.error(error));
    
  }

  saveDocument() {
    return new Promise(resolve => {
      TXTextControl.saveDocument(TXTextControl.streamType.InternalUnicodeFormat, function (e) {
        resolve(e.data);
      });
    });
  }

  loadDocument(document) {
    TXTextControl.loadDocument(TXTextControl.streamType.InternalUnicodeFormat, document);
  }

  loadData(data) {
    TXTextControl.loadJsonData(JSON.stringify(data));
  }

}
```

The function *mergeDocument* accepts the *MergeBody* object and a return format. Implicitly, the function is calling [OAuth](https://docs.textcontrol.com/textcontrol/ds-server/webref.oauth.htm) endpoints to retrieve an access token in the *getAccessToken* function. This access token is then used to call the [DocumentProcessing/Document/Merge](https://docs.textcontrol.com/textcontrol/ds-server/webref.documentprocessing.documentprocessing.document.merge.post.htm) method.

The resulting document is then loaded into the document editor:

![Angular application](https://s1-www.textcontrol.com/assets/dist/blog/2020/12/22/a/assets/angular-app2.webp "Angular application")

### Download the Sample

The Web API can be also used to generate the resulting document as a PDF or any other supported document format. Typically, the templates are created in advance using the document editor and the Web API creates document in separate processes.

Feel free to test this on your own. All you need is a [DS Server trial token](https://www.dsserver.io/trial/) and this sample from GitHub.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [DS Server: Using DocumentEditor in Angular Applications](https://www.textcontrol.com/blog/2020/12/21/ds-server-using-documenteditor-in-angular-applications/llms.txt)
- [Version 30.0 Live Preview](https://www.textcontrol.com/blog/2021/09/22/version-30-live-preview/llms.txt)
- [TX Text Control 30.0 Preview: Improved Online Document Editor Ribbon Design](https://www.textcontrol.com/blog/2021/09/17/tx-text-control-30-preview-improved-online-document-editor-ribbon-design/llms.txt)
- [DocumentViewer: Deploying Forms](https://www.textcontrol.com/blog/2021/07/02/document-viewer-deploying-forms/llms.txt)
- [DS Server: Using DocumentViewer in Angular Applications](https://www.textcontrol.com/blog/2020/12/21/ds-server-using-documentviewer-in-angular-applications/llms.txt)
- [Announcing DS Server Public Beta: Your On-Premise Document Services Cloud](https://www.textcontrol.com/blog/2020/12/18/announcing-ds-server-public-beta/llms.txt)
- [New Product Announcement: DS Server](https://www.textcontrol.com/blog/2020/10/12/new-product-announcement-ds-server/llms.txt)
- [Announcing TX Text Control DS Server 5.0](https://www.textcontrol.com/blog/2026/03/12/announcing-tx-text-control-ds-server-5-0/llms.txt)
- [Introducing DS Server 4.0: Linux-Ready and Container-Friendly](https://www.textcontrol.com/blog/2025/04/30/introducing-ds-server-4-linux-ready-and-container-friendly/llms.txt)
- [DS Server 3.5.0 Released](https://www.textcontrol.com/blog/2024/09/24/ds-server-3-5-0-released/llms.txt)
- [Using the Document Editor in SPA Applications using the removeFromDom Method](https://www.textcontrol.com/blog/2024/09/02/using-the-document-editor-in-spa-applications-using-the-removefromdom-method/llms.txt)
- [DS Server 3.3.0 Released](https://www.textcontrol.com/blog/2024/02/16/ds-server-3-3-0-released/llms.txt)
- [DS Server 3.2.0 Released](https://www.textcontrol.com/blog/2023/11/08/ds-server-3-2-0-released/llms.txt)
- [Impressions from Web Developer Conference WDC 2023 in Hamburg, Germany](https://www.textcontrol.com/blog/2023/09/21/impressions-from-web-developer-conference-wdc-2023-in-hamburg-germany/llms.txt)
- [DS Server 3.1.1 Released](https://www.textcontrol.com/blog/2023/04/12/ds-server-3-1-1-released/llms.txt)
- [Impressions from NDC London 2023](https://www.textcontrol.com/blog/2023/01/30/impressions-from-ndc-london-2023/llms.txt)
- [See Text Control at DEVintersection Fall 2022 in Las Vegas](https://www.textcontrol.com/blog/2022/11/15/see-text-control-at-devintersection-fall-2022-in-las-vegas/llms.txt)
- [Merging Signature Annotations into Documents](https://www.textcontrol.com/blog/2022/10/19/merging-signature-annotations-into-documents/llms.txt)
- [DS Server 3.0: Deploying DS Server without IIS using Docker](https://www.textcontrol.com/blog/2022/10/08/ds-server-30-deploying-ds-server-without-iis-using-docker/llms.txt)
- [DS Server 3.0 Released](https://www.textcontrol.com/blog/2022/10/07/ds-server-3-0-released/llms.txt)
- [Impressions from NDC Oslo 2022](https://www.textcontrol.com/blog/2022/10/04/impressions-from-ndc-oslo-2022/llms.txt)
- [Meet Text Control at NDC Oslo 2022](https://www.textcontrol.com/blog/2022/08/18/meet-text-control-at-ndc-oslo-2022/llms.txt)
- [JavaScript: Avoid Flickering and Visual Updates by Grouping Undo Steps](https://www.textcontrol.com/blog/2022/07/25/javascript-avoid-flickering-and-visual-updates-by-grouping-undo-steps/llms.txt)
- [Reusing TXTextControl Instances in Bootstrap Tabs](https://www.textcontrol.com/blog/2022/06/07/reusing-txtextcontrol-instances-in-bootstrap-tabs/llms.txt)
- [Announcing New Signature Features: Initials and SVG](https://www.textcontrol.com/blog/2022/04/27/announcing-new-signature-features-initials-and-svg/llms.txt)
