How to Save and Download Text in an HTML File in Angular 16 Using HttpClient
Tags: angular, typescript, html
Published: 2024-07-12 13:27:35

In modern web applications, there are scenarios where you need to save text content in an HTML file, read the file, and send its content to a server as form-data. This guide will walk you through achieving this in an Angular 16 application using Angular's HttpClient.

## Prerequisites

Before we dive in, ensure you have the following installed:

- Node.js and npm
- Angular CLI

If you haven't installed Angular CLI, you can do so using npm:

```
npm install -g @angular/cli
```

## Setting Up the Angular Application
Create a new Angular application if you don't have one already:

```
ng new angular-file-upload
cd angular-file-upload
```

Add `HttpClientModule` to your Angular project. Open `app.module.ts` and add it to the imports array:


```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { FileService } from './file.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [FileService],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

## Creating the FileService
First, we need a service to handle file operations. Create a new service:

```
ng generate service file
```

In `file.service.ts`, add the following code:

```
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class FileService {
  private tempFileUrl: string | null = null;

  saveHtmlFile(content: string): string {
    const blob = new Blob([content], { type: 'text/html' });
    this.tempFileUrl = window.URL.createObjectURL(blob);
    return this.tempFileUrl;
  }

  getTempFileUrl(): string | null {
    return this.tempFileUrl;
  }

  revokeTempFileUrl(): void {
    if (this.tempFileUrl) {
      window.URL.revokeObjectURL(this.tempFileUrl);
      this.tempFileUrl = null;
    }
  }
}
```


## Component Implementation
Now, let's implement the component to save text content in an HTML file, read it, and send it as form-data using `HttpClient`.

Update your component (`app.component.ts`) with the following code:

```
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FileService } from './file.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private fileService: FileService, private http: HttpClient) { }

  saveHtmlContent() {
    const content = `
      <html>
        <head>
          <title>Sample HTML File</title>
        </head>
        <body>
          <h1>Hello, World!</h1>
          <p>This is a sample HTML file.</p>
        </body>
      </html>
    `;

    const fileUrl = this.fileService.saveHtmlFile(content);
    console.log('Temporary HTML File URL:', fileUrl);
  }

  async sendFileAsFormData() {
    const fileUrl = this.fileService.getTempFileUrl();
    if (!fileUrl) {
      console.error('No temporary file URL available');
      return;
    }

    try {
      const response = await fetch(fileUrl);
      const content = await response.text();

      // Create a Blob from the content
      const blob = new Blob([content], { type: 'text/html' });
      const formData = new FormData();
      formData.append('file', blob, 'sample.html'); // 'sample.html' is the file name

      // Send the form-data using HttpClient with response type 'blob'
      this.http.post('https://your-api-endpoint.com/upload', formData, { responseType: 'blob' })
        .subscribe(blob => {
          // Handle the blob response
          const downloadUrl = window.URL.createObjectURL(blob);
          const link = document.createElement('a');
          link.href = downloadUrl;
          link.download = 'response-file.html'; // Name of the downloaded file
          link.click();
          window.URL.revokeObjectURL(downloadUrl);

          console.log('File downloaded successfully');
        }, error => {
          console.error('Error sending file content:', error);
        });

    } catch (error) {
      console.error('Error reading file content:', error);
    } finally {
      this.fileService.revokeTempFileUrl();
    }
  }

  clearTempFile() {
    this.fileService.revokeTempFileUrl();
    console.log('Temporary file URL revoked');
  }
}
```

## Template
Update the component template (`app.component.html`) to include buttons for saving and uploading the HTML content:

```
<div>
  <button (click)="saveHtmlContent()">Save Content as HTML</button>
  <button (click)="sendFileAsFormData()">Send Saved HTML as Form-Data and Download Blob</button>
  <button (click)="clearTempFile()">Clear Temporary File</button>
</div>
```


## Explanation

 

- **`saveHtmlContent()`**: This method saves text content in an HTML file and logs the temporary URL.
-  **`sendFileAsFormData()`**:
-  Fetches the file content using the temporary URL. 
-  Creates a Blob from the fetched content. 
-  Creates a **`FormData`** object and appends the Blob to it. 
-  Sends the **`FormData`** object in an HTTP POST request to the specified API endpoint, configuring Angular's **`HttpClient`** to expect a **`blob`** response. 
-  Handles the blob response by creating a download link and triggering a download of the received file. 
-  Logs success or error messages.
-  Revokes the temporary file URL after the request is complete.
-  **`clearTempFile()`**: This method clears the temporary URL to free up memory.