Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

323
Vistas
Calling $http.post in batches and chaining promises

I have a use case where I have to call $http.post(request) on batches of the input data. For this, I created an array of requests. For each of them, I need to get the response of $http.post(), append it to an existing array and pass it to a rendering function. I have to make the next call only when the previous one completes and since $http.post() returns a promise (according to this), I am trying to do this using the reduce function.

function callToHttpPost(request) {
    return $http.post('someurl', request);
}

function outerFunc($scope, someId) {
    let completeArray = [];
    let arrayOfRequests = getRequestInBatches();

    arrayOfRequests.reduce((promiseChain, currentRequest) => {
        console.log(promiseChain);
        return promiseChain.then((previousResponse) => {
            completeArray.push.apply(completeArray, previousResponse.data);
            render($scope, completeArray, someId);
            return callToHttpPost(currentRequest);
        });
    }, Promise.resolve()).catch(e => errorHandler($scope, e, someId));
}

(I have referred MDN and this answer)

But this gives me TypeError: previousResponse is undefined. The log statement shows the first promise as resolved (since it is the initial value passed to the reduce function), but the other promises show up as rejected due to this error. How can I resolve this?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Using vanilla Javascript

If the outerFunc function can be used in an async context (which it looks like it can, given that it returns nothing and the results are passed to the render function as they are built up), you could clean that right up, paring it down to:

async function outerFunc ($scope, someId) {
  const completeArray = []; 

  try {
    for (const request of getRequestInBatches()) {
      const { data } = await callToHttpPost(request);
      completeArray.push(...data);
      render($scope, completeArray, someId);
    }   
  } catch (e) {
    errorHandler($scope, e, someId);
  }
}

The sequential nature will be enforced by the async/await keywords.

Using RxJS

If you're able to add a dependency on RxJS, your can change the function to:

import { from } from 'rxjs';
import { concatMap, scan } from 'rxjs/operators';

function outerFunc ($scope, someId) {
  from(getRequestInBatches()).pipe(
    concatMap(callToHttpPost),
    scan((completeArray, { data }) => completeArray.concat(...data), []) 
  ).subscribe(
    completeArray => render($scope, completeArray, someId),
    e => errorHandler($scope, e, someId)
  );  
}

which revolves around the use of Observable instead of Promise. In this version, the sequential nature is enforced by the concatMap operator, and the complete array of results is reduced and emitted while being built up by the scan operator.

about 4 years ago · Juan Pablo Isaza Denunciar

0

The error was in passing the initial value. In the first iteration of the reduce function, Promise.resolve() returns undefined. This is what is passed as previousResponse. Passing Promise.resolve({ data: [] }) as the initialValue to the reduce function solved the issue.

arrayOfRequests.reduce((promiseChain, currentRequest) => {
    console.log(promiseChain);
    return promiseChain.then((previousResponse) => {
        completeArray.push.apply(completeArray, previousResponse.data);
        render($scope, completeArray, someId);
        return callToHttpPost(currentRequest);
    });
}, Promise.resolve({ data: [] }))
.then(response => {
    completeArray.push.apply(completeArray, previousResponse.data);
    render($scope, completeArray, someId);
    displaySuccessNotification();
})
.catch(e => errorHandler($scope, e, someId));

(edited to handle the final response)

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda