ES6 Modules give us a lot of freedom, so then we can write functions in a different module. An ES6 module is a file containing JS code, and we can import and export it in modules.
Recently, I would like to accomplish a special task, which is passing a variable (being updated) from one module to another one. It's like a global variable, and it should be straightforward if we have everything in one file, for example:
var globalTooltips = [];
function veryComplicatedProcess(data){
//some complicated logic
const newData = shapeMe(data)
saveData(newData);
// additional task
const tooltips = getTooltips(newData.someField);
globalTooltips.concat(tooltips);
}
function exportAll (rawData) {
rawData.forEach(data => {
veryComplicatedProcess(data);
});
}
function process() {
const rawData = somethingOtherFunction();
exportAll(rawData);
// save tooltips
saveTooltips(globalTooltips);
}
process();
As you see, the goal is to add an additional task (saveTooltips
) to the existing process. Note that the getTooltips
can be done during the existing data processing, but it's hard to get from the existing result. So it's ideal to save the tooltips using the global variable and then save them after the existing process is done.
However, the actual logic is much more complicated than this, and we use ES6 Modules, which means verComplicatedProcess()
is in a different module. The challenge here is how to pass the global variable from one module to another module.
The first thing I thought of is using Closure, which allows the inner function to access the outer function. But in order to use Closure, we have to nest the functions inside the main function, which is process(),
in my case. Something like,
function process() {
let globalTooltips = [];
const rawData = somethingOtherFunction();
function exportAll (rawData) {
rawData.forEach(data => {
function veryComplicatedProcess(data){
//some complicated logic
const newData = shapeMe(data)
saveData(newData);
// additional task
const tooltips = getTooltips(newData.someField);
globalTooltips.concat(tooltips);
}
});
}
// save tooltips
saveTooltips(globalTooltips);
}
But this is not practical in my case, because the inner function is way more complicated than the demo code above.
The good news is we could use a Context module to resolve this issue easily in ES6 Modules.
First, I created a Context module named globalContext.js, like:
const globalContext = {
tooltips: [],
};
export default globalContext;
Then in the main.js, I imported it as:
import globalContext from "./globalContext";
import veryComplicatedProcess from "./veryComplicatedProcess.js";
function exportAll (rawData) {
rawData.forEach(data => {
veryComplicatedProcess(data);
});
}
function process() {
const rawData = somethingOtherFunction();
exportAll(rawData);
// save tooltips
saveTooltips(globalContext.tooltips);
}
process();
Also, imported globalContext
in another module containing veryComplicatedProcess
function, like:
import globalContext from "./globalContext";
export default function veryComplicatedProcess(data){
//some complicated logic
const newData = shapeMe(data)
saveData(newData);
// additional task
const tooltips = getTooltips(newData.someField);
globalContext.tooltips.concat(tooltips);
}