Search code examples
javascriptreactjspromisees6-promise

Exporting Promise API calls for reusing


My question is about unrecognized behavior of a react app. I wrote promises for API calls and exported them in one file as many components will use them. Problem is that those exported calls are executed even before I call them on app load.

//in commonAPI.js with other exports of similar promises
export var loadDesignationTypes = new Promise(function (resolve, reject) {

    axios.get('http://localhost:7002/commonAPI/getDesignations')
        .then(response => {
            if (response.data.success) {
                var designationObjAr = response.data.resultEmployeeDesignations;
                resolve(designationObjAr);
            }
        }).catch(function (error) {
            console.log("designation err " + error);
            reject(error)
        });
});

Inside components :

import { loadDesignationTypes, loadDepartmentTypes,
          loadLocationTypes, loadMaritialStatus } from '../../../CommonAPIs';

 //in a function
 const results = await Promise.all([loadDesignationTypes,
            loadDepartmentTypes,loadLocationTypes, loadMaritialStatus]);

What confuses me even more is that other promise exports which are not called inside component who resides in same file with called promise are executed as well.


Solution

  • The module is currently running the new Promise(.. block synchronously, when the module's code is run, while the interpreter is trying to figure out what each module imports and exports. If you want the axios.get to run on demand, rather than automatically, you should export a function that creates a Promise when called, rather than a plain Promise.

    You should also take care not to use the explicit Promise construction antipattern - simply return the Promise chain instead:

    export var loadDesignationTypes = () => axios.get('http://localhost:7002/commonAPI/getDesignations')
      .then(response => {
        if (response.data.success) {
          return response.data.resultEmployeeDesignations;
        }
        // if not successful, you probably want to throw an error:
        throw new Error('Not successful');
      }).catch(function (error) {
        // If this console.log statement isn't necessary,
        // better to leave the catch out entirely
        // and leave error handling to the consumer
        console.log("designation err " + error);
        throw error;
      });
    

    Then, in the consuming module, call the function when using it with Promise.all:

    const results = await Promise.all([
      loadDesignationTypes(),
      // etc