Search code examples
d3.jspromiseangular2-services

Outputting Value of Promise during multiple parses


I am loading a promise from d3.csv and then making multiple changes to the returned array in subsequent .then calls.

I need to out put to the html (Angular 2) the sate of the array before each change, I can do this using the ( variable | async ) but it will update with each change and I need to output the state before each change.

I tried to clone the promise, but all clones just point to the same promise. Any variables are out of scope in the changes, and the parent scope is not reachable.

data = d3.csv promise
data.then(methodB()). // HTML | async Output Required of Array before changes
then(methodB()) // HTML | async Output Required of Array before changes
etc..
etc..
etc..
(There are around 15 methods applied to the data as it is munched and analyzed)

What is the best way to achieve this?


Solution

  • Assuming :

    • you have a starting promise named csvPromise, which delivers array
    • the methods to be applied are methodA, methodB, methodC etc, each of which accepts Array
    • each method either returns a mutation of the input array or delivers the mutation via a Promise
    • changes to the array are cumulative, method-on-method
    • you have a synchronous function output() which will accept the original array and each mutation

    then a pattern like this will do the job :

    csvPromise
    .then(function(arr) {
        output(arr); // observe initial array as delivered by csvPromise
        return methodA(arr);
    })
    .then(function(arr) {
        output(arr); // observe array after application of methodA
        return methodB(arr);
    })
    .then(function(arr) {
        output(arr); // observe array after application of methodB 
        return methodC(arr);
    })
    etc..
    etc..
    etc..
    .then(function(arr) {
        output(arr); // observe array after application of final method
    }).catch(function(error) {
        console.log(error); // any error thrown from anywhere in the chain will arrive here 
    });
    

    The pattern can be proceduralised by building the chain dynamically as follows :

    var methods = [methodA, methodB, methodC, ...]; // list of methods (uncalled at this point)
    return methods.reduce(function(promise, method) {
        return promise.then(function(arr) {
            output(arr); // observe result of previous stage
            return method(arr);
        });
    }, csvPromise)
    .then(function(arr) {
        output(arr); // observe array after application of final method
    }).catch(function(error) {
        console.log(error); // any error thrown from anywhere in the chain will arrive here 
    });
    

    The most likely violation of the assumptions would be that output() was itself asynchronous, in which case :

    var methods = [methodA, methodB, methodC, ...]; // list of methods
    return methods.reduce(function(promise, method) {
        return promise.then(function(arr) {
            return output(arr).then(function() {
                return method(arr);
            });
        });
    }, csvPromise)
    .then(function(arr) {
        output(arr); // observe array after application of final method
    }).catch(function(error) {
        console.log(error); // any error thrown from anywhere in the chain will arrive here 
    });