An Array of objects is considered NULL if it does not contain any values before being iterated through

Working with Files in TypeScript (Angular 8) has led me to Encode the files in Base64 using the code below:

  private async convertToBase64(evidences: Array<EvidenceToDisplay>): Promise<Array<EvidenceToDownload>> {
    const results: Array<EvidenceToDownload> = [];
    for (const evidence of evidences) {
      const evidenceToDownload: EvidenceToDownload =  {
        base64: null,
        name: '',
        extension: '',
      };
      const reader = new FileReader();
      reader.onloadend = function() {
        evidenceToDownload.base64 = reader.result;
      };
      reader.readAsDataURL(evidence.file);
      evidenceToDownload.name = evidence.name;
      evidenceToDownload.extension = this.getExtensionFromName(evidence);
      results.push(evidenceToDownload);
    }

    return results;
  }

The result is then obtained in another method as shown below:

  public async downloadEvidences() {
            const zip = new JSZip();
            let consecutive = 1;
            const allEvidences: Array<EvidenceToDisplay> = this.mergeEvidenceArray(this.manualEvidences, this.mobilityEvidences);
            const evidencesToDownload: Array<EvidenceToDownload> = await this.convertToBase64(allEvidences);
            console.log(evidencesToDownload);
            for (let i = 0; i < evidencesToDownload.length; i++) {
              console.log(evidencesToDownload[i].base64);
              zip.file(EVIDENCE + DASH + consecutive + DOT + evidencesToDownload[i].extension, evidencesToDownload[i].base64,
                 { binary : true, base64: true, compression : 'DEFLATE' });
              consecutive++;
            }
            zip.generateAsync({type: 'blob'}).then(function(blob) {
              FileSaver.saveAs(blob, 'test' + DOT + ZIP);
            });
          }

After observing the logs from the console, it became clear that there was a discrepancy between the initial and subsequent results. The issue seems familiar to cases involving "array.forEach" compared to a standard loop. Any idea why this might be happening?

To address the problem, I switched to encoding the file in binary instead of base64, eliminating the need for a file reader. This change helped resolve the inconsistency in logging results.

  public async downloadEvidences() {
    const zip = new JSZip();
    let consecutive = 1;
    const allEvidences: Array<EvidenceToDisplay> = this.mergeEvidenceArray(this.manualEvidences, this.mobilityEvidences);
    for (let i = 0; i < allEvidences.length; i++) {
      const extension = this.getExtensionFromName(allEvidences[i]);
      const MIMEType = this.getMIMEtype(extension);
      const blob = new Blob([allEvidences[i].file], { type: MIMEType });
      zip.file(EVIDENCE + DASH + consecutive + DOT + extension, blob,
        { binary : true, compression : 'DEFLATE' });
     consecutive++;
    }
    zip.generateAsync({type: 'blob'}).then(function(blob) {
      FileSaver.saveAs(blob, 'test' + DOT + ZIP);
    });
  }

For additional insights, reading files asynchronously proved to be beneficial. Check out this resource:

Answer №1

If you want to tackle this issue, one solution is to create an array of promises within the convetTob64 function. Below, I have provided a sample implementation with your updated code.

async function base64Converter(evidences) {
  return Promise.all(evidences.map(evidence => new Promise((resolve, reject) => {
    const evidenceToConvert = {
      base64: null,
      name: '',
      extension: '',
    };
    const reader = new FileReader();
    reader.onloadend = function() {
      evidenceToConvert.base64 = reader.result;
      resolve(evidenceToConvert);
    };
    reader.readAsDataURL(evidence);

    evidenceToConvert.name = evidence.name;
    evidenceToConvert.extension = '.someExtension';
  })));
}

async function handleFileInputChange(event) {
  const evidencesArray = await base64Converter(Object.values(event.target.files));
  console.log(evidencesArray);

}
<input type="file" onchange="handleFileInputChange(event)" multiple />
<div id="message"></div>

Answer №2

One possible explanation for this occurrence is that the information is not fully loaded when the initial console.log statement is executed due to the asynchronous nature of reader.onloadend.

It is advisable to pause until the data has finished loading before exiting the function convertTob64().

Answer №3

Issue resolved! Grateful for those who took the time to read and assist me. I have now switched to reading the file in binary format instead of base64.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Use joi to validate the entire request object

In order to ensure the validity of request input before calling the controller logic, I developed a middleware for that purpose. Let's suppose we have a route for "getting user by id". const usersController = require('../controllers/users.js&ap ...

When the session times out in Angular 5, the previous user's credentials remain on the page instead of being replaced with the current user's information

When switching from one user to another in Angular 5, I am facing an issue where the previous user's credentials are displayed instead of the current user's until I refresh the page. I have tried using the localstorage.clear() method but it doesn ...

Could anyone provide an explanation of the current situation in this section of the code?

I am currently working on a piece of code that looks like this: ruter.get('/', async function (_, res) { const [categories, items] = (await Promise.all([ db.query('SELECT * FROM categories'), db.query('SELECT * FROM invento ...

How to conditionally apply a directive to the same tag in Angular 4

I am implementing angular 4 and have a directive in my template for validation purposes. However, I would like to first check if a specific condition is true before applying the directive. Currently, my code looks like this: <div *ngIf="groupCheck; els ...

How can I display SQL results in a Jade page using Node, Express, and MySQL?

My application built with Node.js and Express is connected to a MySQL database for monitoring purposes. The code structure is as follows: In the Node file: app.get('/banners', function(req,res){ connection.query("SELECT * FROM banner_store_ ...

Utilizing HTML to call a function and fetching data from AngularJS

I've been struggling to retrieve the value after calling a function in my HTML file. Despite trying various methods after conducting research, I have not achieved success yet. Take a look at the code below: HTML: <div class="form-group"> & ...

Checking conditions sequentially in Angular

I have a unique use case that requires me to verify certain conditions. If one condition fails, I should not proceed to the next one. Instead, based on the failed condition, I need to display a dialog with a title and description explaining what went wrong ...

Personalize your BigBlueButton experience with custom HTML 5 client modifications

Does anyone know how to remove the three-dot options menu button in the Big Blue Button HTML 5 client that's installed on Ubuntu? Our setup involves displaying the html5 client inside an iframe, so we need to handle the meeting leave and end functions ...

Avoiding flickering when the browser back button is clickedAvoiding the flickering effect

As I work on developing an Asp.Net application, a challenge has arisen. In order to prevent users from navigating back to the login page after logging in, I have implemented JavaScript code successfully. However, when clicking the browser's back butto ...

Enhancing current interfaces

I'm exploring Koa and the module system in Node.js. Although I'm not asking about a specific koa question, all the code I'm working with involves using koa. In Koa, every request is defined by the Request interface: declare module "koa" { ...

Troubleshooting Issue: XMLHttpRequest Incompatibility with Internet Explorer

I'm having an issue with the script below. It works fine on Firefox and Chrome but doesn't seem to work on IE. I've tried various solutions, including lowering the security settings on my browser, but it still won't work. function se ...

Use ng-repeat to extract information from an array and populate it into a datalist

I've already tried searching for a solution to my issue on Google, but I couldn't find anything that really helped me. I'm looking to create an input field that also functions like a dropdown. This way, I can either type in my own data or se ...

Deployment failure of AWS CDK caused by Error: Lambda Function Invalid

I'm in the process of integrating a Lambda authorizer into my REST API using AWS CDK. const api = new apigw.RestApi(this, 'apiname', { defaultCorsPreflightOptions: { allowOrigins: apigw.Cors.ALL_ORIGINS } }); const authorizerFuncti ...

The development mode of NextJS is experiencing issues, however, the build and start commands are functioning normally

Just finished creating a brand new Next app (version: 12.0.7) using Typescript and Storybook. Everything seems to be working fine - I can successfully build and start the server. However, when I try to run dev mode and make a request, I encounter the follo ...

Issues with synchronizing Firebase and Node.js?

https://i.stack.imgur.com/3fwRO.png Here is the code snippet I used in my Node.js application: for(var v in sna.val()){ console.log("each "+va); console.log(v); var fourthRef = ref.child(val+'/reservation/&apos ...

Do I need to use Node.js for Angular 2, or can I run it on an Apache server instead

Can XAMPP or Apache be used instead of the Node.js npm server when working with Angular 2? ...

What is the best way to exchange configuration data among Javascript, Python, and CSS within my Django application?

How can I efficiently configure Javascript, Django templates, Python code, and CSS that all rely on the same data? For example, let's say I have a browser-side entry widget written in Javascript that interacts with an embedded Java app. Once the user ...

Tips for customizing bootstrap code for registration form to validate against duplicate emails?

The contact_me form utilizes default code to handle success or failure responses from the server. The code calls msend_form.php for communication with the database and always returns true. It allows checking for pre-existing email addresses in the database ...

Excessive geolocation position responses in Angular 5

I am trying to implement an Angular 5 component that will continuously fetch my current location every 3 seconds if it has changed. Here is a snippet of my code: export class WorkComponent implements OnInit { constructor(private userService: UserService ...

AngularJS checkbox validation requires a minimum of two checkboxes to be selected

When using AngularJS, I am looking to create a validation rule where a minimum of 2 checkboxes must be checked for the input to be considered valid. Here is what I have attempted: <div ng-repeat="item in items"> <label><input type="chec ...