skip to Main Content

In my Angular program, have a class called myObj and an array called myArrayObj, that contains many instances of myObj.

I am currently storing it into Blob and write into file, as shown below.

    const blob = new Blob([JSON.stringify([myArrayObj])], { type: 'application/json' });
    saveAs(blob, `${myFileName}.json`);

To retrieve content from file, I have another set of codes.

    const fileReader = new FileReader();
    fileReader.onload = (e) => {
       const content = e.target?.result;
       if (typeof content === 'string') {
          const myArrayObj = JSON.parse(content);
       }

My problem is that I want to save a single setting object (mySettingObject) into the file, before this array. How do I do that? How do I retrieve the setting object and array later?

2

Answers


  1. We can create a complex object, with two properties settings (which holds mySettingObject) and array, then we perform the download.

    downloadFile() {
      const mySettingObject = {
        qwerty: 1,
      };
      const myArrayObj = {
        settings: mySettingObject,
        array: [{ test: 1 }, { test: 2 }, { test: 3 }],
      };
      const myFileName = 'test';
      const blob = new Blob([JSON.stringify(myArrayObj)], {
        type: 'application/json',
      });
      this.saveAs(blob, `${myFileName}.json`);
    }
    
    saveAs(blob: any, filename: any) {
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      a.click();
      window.URL.revokeObjectURL(url);
    }
    

    On upload we use the FileReader, readAsText to read in UTF-8 format. Finally, we again re-access these properties using the same property names.

    onSelectFile(event: any) {
      this.selectedFile = event.target.files[0];
      const fileReader = new FileReader();
      fileReader.readAsText(this.selectedFile, 'UTF-8');
      fileReader.onload = () => {
        const data = JSON.parse(<string>fileReader.result);
        console.log('settings', data.settings);
        console.log('settings', data.array);
      };
      fileReader.onerror = (error) => {
        console.log(error);
      };
    }
    

    Full Code:

    import { Component } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      template: `
        <button (click)="downloadFile()">download</button>
        <hr/>
        <input type='file' (change)="onSelectFile($event)">
      `,
    })
    export class App {
      name = 'Angular';
      selectedFile: any;
    
        downloadFile() {
          const mySettingObject = {
            qwerty: 1,
          };
          const myArrayObj = {
            settings: mySettingObject,
            array: [{ test: 1 }, { test: 2 }, { test: 3 }],
          };
          const myFileName = 'test';
          const blob = new Blob([JSON.stringify(myArrayObj)], {
            type: 'application/json',
          });
          this.saveAs(blob, `${myFileName}.json`);
        }
    
        saveAs(blob: any, filename: any) {
          const url = window.URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.href = url;
          a.download = filename;
          a.click();
          window.URL.revokeObjectURL(url);
        }
    
        onSelectFile(event: any) {
          this.selectedFile = event.target.files[0];
          const fileReader = new FileReader();
          fileReader.readAsText(this.selectedFile, 'UTF-8');
          fileReader.onload = () => {
            const data = JSON.parse(<string>fileReader.result);
            console.log('settings', data.settings);
            console.log('settings', data.array);
          };
          fileReader.onerror = (error) => {
            console.log(error);
          };
        }
    }
    
    bootstrapApplication(App);
    

    Stackblitz Demo

    Login or Signup to reply.
  2. My problem is that I want to save a single setting object (mySettingObject) into the file, before this array.

    You can’t. At least, not directly.

    Normally, JSON parsers only work on one root object. Therefore, you’d have to serialize an entire object that contains your array as well.

    JSON.stringify({
      mySettingsObject,
      myArrayObject
    });
    

    In this case, there’s a singular root object that you can reference properties on, which is perfectly fine.

    An alternative… there is a variant of JSON that uses line delimiters called ND-JSON. This allows multiple root objects, but the usual use of it is for multiple objects of the same or similar type. While this isn’t a requirement, I’d think your use case is inappropriate.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search