Experiencing 429 Too Many Requests error on Angular 7 while attempting to perform multiple file uploads

Whenever I attempt to upload a large number of files simultaneously, I encounter an issue.

The API interface only allows for the submission of one file at a time, requiring me to call the service for each individual file. Currently, my code looks like this:

onFilePaymentSelect(event): void {
    if (event.target.files.length > 0) {
      this.paymentFiles = event.target.files[0];
    }
    let i = 0;
    let save = 0;
    const numFiles = event.target.files.length;
    let processed = 0;
    if (event.target.files.length > 0) {
      while (event.target.files[i]) {
      const formData = new FormData();
      formData.append('file', event.target.files[i]);
      this.payrollsService.sendFilesPaymentName(formData).subscribe(
      (response) => {
        let added = null;
        processed++;
        if (response.status_message === 'File saved') {
          added = true;
          save++;
        } else {
          added = false;
        }
        this.payList.push({ filename, message, added });
      });
    i++;
  }
}

Essentially, I am using a loop to sequentially send each file to the API, but when handling a large volume of files, I receive a "429 too many request" error. Is there any way to optimize this process?

Answer №1

If you work with observables, it becomes easier to understand the task at hand compared to using imperative programming.

Typically, a browser can handle 6 requests in parallel and queue the rest. However, we don't want the browser to manage the queue for us. This is especially relevant in a node environment where such management may not be available.

What we aim for is efficient file uploads by queuing them and processing 5 requests in parallel continuously, while keeping 1 free for other app requests.

To demonstrate this concept, let's create some mock data:

function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

const mockPayrollsService = {
  sendFilesPaymentName: (file: File) => {
    return of(file).pipe(
      // simulating network latency between 500ms to 1.5s
      delay(randomInteger(500, 1500))
    );
  }
};

// an array containing 50 mocked files
const files: File[] = Array.from({ length: 50 })
  .fill(null)
  .map(() => new File([], ""));

The above code should be self-explanatory. We are generating mocks to simulate the behavior without direct access to your application.

Now, onto the main part:

const NUMBER_OF_PARALLEL_CALLS = 5;

const onFilePaymentSelect = (files: File[]) => {
  const uploadQueue$ = from(files).pipe(
    map(file => mockPayrollsService.sendFilesPaymentName(file)),
    mergeAll(NUMBER_OF_PARALLEL_CALLS)
  );

  uploadQueue$
    .pipe(
      scan(nbUploadedFiles => nbUploadedFiles + 1, 0),
      tap(nbUploadedFiles =>
        console.log(`${nbUploadedFiles}/${files.length} file(s) uploaded`)
      ),
      tap({ complete: () => console.log("All files have been uploaded") })
    )
    .subscribe();
};

onFilePaymentSelect(files);
  • We use from to process files individually as observables
  • Through map, we prepare a request for each file, but since we don't subscribe yet, the request remains pending
  • With mergeMap, we control the concurrency level to run a maximum of 5 calls simultaneously
  • Using scan for visual tracking (counting successful uploads)

Check out the live demo here: https://stackblitz.com/edit/rxjs-zuwy33?file=index.ts

Observe the console to see how we handle the uploads sequentially rather than all at once.

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

Disabling the range selection in the mat-date-range-picker when the date is disabled

I am trying to use the mat-date-range-picker feature to prevent users from selecting a date range that includes disabled dates. In the provided example (available at this stackblitz url: https://stackblitz.com/edit/angular-rbeehp?file=src%2Fapp%2Fdate-ran ...

Retrieve Content from a Different Web Page Using Ajax

I recently received permission from another website to pull their RSS feeds, and now I'm trying to figure out what to write in TAG1 and TAG2. This is the specific issue I'm facing: Here is the HTML code (it's an ajaxed page) <!doctype ht ...

Tips for displaying JSON data by formatting it into separate div elements for the result object

Having recently started using the Amadeus REST API, I've been making AJAX calls to retrieve data. However, I'm facing a challenge when it comes to representing this data in a specific format and looping through it effectively. function showdataf ...

Error message stating: "The 'MktoForms2' property is not recognized within the scope of 'Window & typeof globalThis'."

Encountering the following error message: (Property 'MktoForms2' does not exist on type 'Window & typeof globalThis') while working with react and typescript useEffect(() => { window.MktoForms2.loadForm("//app-sj11.marke ...

Attempting to compile TypeScript by referencing ng2-bootstrap using Gulp within Visual Studio

I've been struggling with this issue for a few days now, and I'm really hoping someone can help me out. Currently, I am experimenting with Angular2 in an aspnet core project. The setup involves using a gulpfile.js to build .ts files and transfer ...

Issues with JQuery list selectors

Many individuals have raised concerns about selectors in the past, but no matter what I try, my code seems right yet it doesn't work as intended. My situation involves a list of actions that are displayed or hidden when their corresponding "folder" is ...

Tips for ensuring that Angular2 waits for a promise to resolve before rendering a component

Yes, I did a thorough search on Google before posting this question and unfortunately, the provided solution did not solve my issue. A Little Background I am working on an Angular 2 component which fetches data from a service and needs to carry out certa ...

What are the reasons behind memory leaks and decreased rendering speed when I exit and then reopen a React component (specifically Material-Table)?

I have been working on a basic React example for learning purposes, and I incorporated the use of material-table in one of my components. However, I noticed that each time I change pages and reopen the component (unmount and mount), the rendering speed of ...

JQuery Submission with Multiple Forms

Hey everyone! I have a jQuery form with multiple fieldsets that switch between each other using jQuery. Eventually, it leads to a submit button. Can someone assist me by editing my jfiddle or providing code on how I can submit this data using JavaScript, j ...

Is there a way to simulate AWS Service Comprehend using Sinon and aws-sdk-mock?

As a newcomer to Typescript mocking, I am trying to figure out how to properly mock AWS.Comprehend in my unit tests. Below is the code snippet where I am utilizing the AWS Service Comprehend. const comprehend = new AWS.Comprehend(); export const handler ...

Encountering issues with loading Angular formControl

I've been going through an Angular tutorial on forms, which you can check out here. In my 'datasources.component.html' file, I have the following code: <form [formGroup]="queryForm"> <label>Query: <input type="text" formCont ...

After an ajax call in ASP .NET MVC3 using Razor, jQuery may not function properly

When I perform a post back to obtain a partial view using ajax, I utilize the following code to render the partial view within a div named 'DivSearchGrid'. <script type ="text/javascript" > $('#Retrieve').click(function ( ...

Error message stating 'Module not found' is displaying in the browser console

As a beginner with Angular CLI, I recently executed the following commands at the root of my Angular project. issue-management\src\webui>ng generate module pages\dashboard issue-management\src\webui>ng generate component pag ...

Having issues with npm python-shell integration within electron framework

I'm currently attempting to establish a connection between a python script and an Electron app by utilizing the npm's python-shell package. The requirement is for the script to be executed whenever a button is clicked. So, let's assume my d ...

Guide: Initiating an action in NuxtJs

I am attempting to trigger an action in my Vue component from my Vuex store. Below is the content of my aliments.js file in the store: import Vue from 'vue'; import Vuex from 'vuex'; import axios from 'axios'; Vue.use(Vuex, ...

Angular automatically substitutes a string with the location of an image

I am currently working on developing a frame data application for a fighting game in angular/ionic, which is still relatively new to me. The app will consist of individual spreadsheets for each character showcasing the attributes of all their moves. Check ...

An alternative to passing AngularJS expressions to PHP or Ajax

Within my PHP/HTML file, I have an AngularJS expression that looks like this: {{data.po_id}} This expression is included as <td>{{data.po_id}}</td> within a table row. I am trying to use this expression as a parameter for a PHP function in t ...

Why is it beneficial to define a function as an immediately invoked function expression that returns another function?

The pattern of using IIFE (Immediately Invoked Function Expression) in three.js source code is quite common. Interestingly, removing the IIFE doesn't seem to have any impact on the functionality. It appears that using a named function instead of an an ...

Ways to eliminate a specific array from another array using JavaScript

0: {id: 1553825061863, name: "Thai Milk Tea", qty: "1", total_amount: 9500, toppings: 500, …} 1: {id: 1553825061863, name: "Thai Milk Tea", qty: "1", total_amount: 9500, toppings: 500, …} 2: {id: 1553825061863, name: "Thai Milk Tea", qty: "1", total_am ...

Guide on setting the number of records to display on each page using ngx pagination in Angular 4

Successfully integrated ngx pagination in my Angular 4 project and it's functioning well. However, I'm facing a challenge in displaying the number of records per page as (Showing: 1 - 10 / 25). I've attempted to solve it but unfortunately ha ...