5
\$\begingroup\$

I am working on a website using .NET Razor Pages. I have multiple pages that share JavaScript code. I'm using vanilla JavaScript. I have to perform actions related to mapping using leaflet. Most of this logic is similar, drawing on a map, calculating distances/areas/intersection, changing layers, changing routes visible... There are very small differences with each page. For example, on one page we might allow drawing polygons where on another page we might not. I am using flags as a global variable. I have a script inside every page that sets some flags like this:

<script>
    const bgLayerName = '@Model.DefaultBackgroundLayer';
    const infoLayerName = '@Model.DefaultInformationLayer';
    const onlyEnablePolygon = true;
    const allowMultiplePolygons = true;
</script>

Then in my shared code I will have conditionals for each flag:

if (typeof onlyEnablePolygon !== 'undefined' && onlyEnablePolygon) {
    // conditional code...
}

How can or should I improve this? My shared JavaScript is around 1K loc and contains no needless abstractions and I would like to keep it simple. But I feel uneasy about global variables

\$\endgroup\$
2
  • \$\begingroup\$ "My shared JavaScript is around 1K loc and contains no needless abstractions" - are you using any sort of modularisation? OOP? Does the shared code use/introduce globals? \$\endgroup\$
    – Bergi
    Commented Sep 25 at 18:51
  • \$\begingroup\$ Will you ever have multiple maps (with potentially different configurations) on the same page? If yes, how does your code handle them currently? If no, how would you approach this (with minimal changes to your code, I guess, introducing abstractions only where needed)? \$\endgroup\$
    – Bergi
    Commented Sep 25 at 18:52

1 Answer 1

5
\$\begingroup\$

You can find inspiration here on how to avoid polluting the global namespace: https://developer.mozilla.org/en-US/docs/Glossary/IIFE#avoid_polluting_the_global_namespace

Your shared JS would still contain 1 global (the function) that you could call with a config object like

<script>
    initializeMapLogic({
      bgLayerName : '@Model.DefaultBackgroundLayer',
      infoLayerName : '@Model.DefaultInformationLayer',
      onlyEnablePolygon : true,
      allowMultiplePolygons : true
    });
</script>
\$\endgroup\$
4
  • 1
    \$\begingroup\$ "an IIFE that you call" - huh? \$\endgroup\$
    – Bergi
    Commented Sep 25 at 18:53
  • 1
    \$\begingroup\$ Notice that initializeMapLogic is still a global. \$\endgroup\$
    – Bergi
    Commented Sep 25 at 18:54
  • \$\begingroup\$ This is not an IIFE. As your link says, another—perhaps clearer—name for the pattern is “self-executing anonymous function.” This function is neither self-executing nor anonymous. This is just calling a function—which is a good suggestion, but this answer should not mislead about the meaning of “IIFE.” An IIFE is when you define and invoke a function all at once, e.g. (function () { /*…*/ })(); or (() => /*…*/)();. A real IIFE wouldn’t actually help much here; the whole point is to have the single shared initializeMapLogic function that you could call in each page. \$\endgroup\$
    – KRyan
    Commented Sep 25 at 19:45
  • \$\begingroup\$ All fair points. I updated my answer. \$\endgroup\$
    – konijn
    Commented Sep 25 at 20:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.