Damon
Damon

Reputation: 10799

How to properly resolve and use promise.all()

I am trying to use window.fetch and promises to build an ajax pattern where I have:

  1. Controllers that initiate the calls
  2. Services that define the urls and parameters necessary for the app
  3. Utilities to provide generic functions for fetching

I can't seem to get the dataflow to fall through all the functions quite right so I think that I must have something hooked up wrong. I think it is probably in the Promise.all() because the .then() in the utilities is firing before the call has actually completed so the response is blank.

My code is below (and there is a gist as well). I haven't used promises much before so I may be coming at this all wrongy...

controller.js

import {fetchHistoryData} from '/service'

function initChart(config = this.defaultConfig){
    fetchHistoryData()
        .then((response)=> {
            buildChart();
        }).catch(()=>{
        console.error('Could not get data.');
    });
}
}

fetchutils.js

function fetchData(url, options = {mode: 'cors'}, formatter = ((data)=>data)){
    console.log(url);
    return window.fetch(url, options)
        .then(status)
        .then(formatter)
        .then(function(data){
            return data;
        })
        .catch(throwError);
}

service.js

import {fetchData} from './fetchUtils'

export function fetchHistoryData(){
    return Promise.all([fetchHistory('set1'), fetchHistory('set2')]);
        //.then((result)=>result); ??
}

function fetchHistory(name){
    return new Promise((resolve)=>{
        const url = createHistoryUrl(name);
        resolve (fetchData(url, {mode:'no-cors'}, historyFormatter));
    });
}

https://gist.github.com/thedamon/86601ba009bfd05cb791

Upvotes: 0

Views: 122

Answers (1)

mido
mido

Reputation: 25034

there are few issues with this code,

  • initChart function is not returning anything,
  • you are wrapping promises with promises in fetchHistory, not sure why
  • in case you are wondering, Promise.all would return an array of results( i.e one result per promise)
  • I can understand the default formatter method, but next operation in the then chain does nothing in fetchData,

effectively your code can be reduced to:

//controller.js

import {fetchHistoryData} from '/service'

function initChart(config = this.defaultConfig){
  return fetchHistoryData()
    .then(response=> buildChart())
    .catch(()=>  console.error('Could not get data.'));
}

//fetchutils.js

function fetchData(url, options = {mode: 'cors'}, formatter = data => data ){
  console.log(url);
  return window.fetch(url, options)
    .then(status)
    .then(formatter)
    .catch(throwError); // not sure if catch is need here
}

//service.js 

import {fetchData} from './fetchUtils'

export function fetchHistoryData(){
  return Promise.all(['set1', 'set2'].map(fetchHistory));
    //.then((result)=>result); ??
}

function fetchHistory(name){
  return fetchData(createHistoryUrl(name), {mode:'no-cors'}, historyFormatter);
}

Upvotes: 1

Related Questions